I have something that really works.
I forgot that Optional is NilLiteralConvertible . Thus, we can provide 2 options for the conversion function, and this will not fail. Basically, there is a restriction on T where T: NilLiteralConvertible
class Thing<T>{ var item: T init(_ item: T){ self.item = item } } struct Actions{ // Provide 2 variations one with T the other where T: NilLiteralConvertible // variation 1 for non-optionals static func convertIntForThing<T>(string: String, thing:Thing<T>) -> T{ return convertStringToInt(string, to: T.self) } // variation 2 for optionals static func convertIntForThing<T where T: NilLiteralConvertible>(string: String, thing:Thing<T>) -> T{ return convertStringToInt(string, to: T.self) } static func convertStringToInt<T>(string: String, to: T.Type) -> T{ debugPrint("Converting to ---> \(to)") return Int(string)! as! T } static func convertStringToInt<T where T: NilLiteralConvertible>(string: String, to: T.Type) -> T{ debugPrint("Converting to ---> \(to)") let value = Int(string) if let _ = value{ return value as! T } let other: T = nil return other } } func testExample() { // this WORKS: let thing1 = Thing<Int>(0) thing1.item = Actions.convertIntForThing("1", thing: thing1) let thing2 = Thing<Int?>(0) thing2.item = Actions.convertIntForThing("", thing: thing2) } testExample()
source share