Is there a way in Swift to retrieve the type of an initializer expression in order to define another variable of the same type?
Usage in accessor macros
Accessor macros like the DictionaryStorage
example could benefit from that and would allow users of the macro to omit type annotations if given an initializer expression.
Example from the evolution proposal
Swift evolution proposal SE-0389: attached macros introduces attached accessor macros using the example of a DictionaryStorage
macro, e.g.
struct MyStruct {
var storage: [AnyHashable: Any] = [:]
@DictionaryStorage
var name: String
@DictionaryStorage(key: "birth_date")
var birthDate: Date?
}
get's expanded into:
struct MyStruct {
var storage: [String: Any] = [:]
var name: String {
get {
storage["name"]! as! String
}
set {
storage["name"] = newValue
}
}
var birthDate: Date? {
get {
storage["birth_date"] as Date?
}
set {
if let newValue {
storage["birth_date"] = newValue
} else {
storage.removeValue(forKey: "birth_date")
}
}
}
}
Initial values
In Swift declarations code authors are allowed to omit type annotations if the type can be inferred from an initializer expression, e.g. write
let greeting = "Hallo, world!"
instead of the more complete
let greeting: String = "Hallo, world!"
If in the above example of the DictionaryStorage
macro the macro user had written:
@DictionaryStorage var name = "Rezart"
the macro would be unable to expand, because it would not know to which type to cast the return value of the dictionary, e.g.
var name: String {
get {
storage["name"]! as! <WHAT SHALL GO HERE?>
}
...
}
Our current solution
At Astzweig we developed swift-syntax-literals specifically for this problem, in order to allow users of our macros to omit type annotation for at least some well known literals. Because of this limitation and because this approach doesn't have the power of Swift's type inference, we are looking for a better way.