In Swift, how to extend a typealias?
AFAIK, no.
Consider the following example:
typealias Height: Float
extension: Height {
}
Here Height
is not a new type, it's just a label for Float
so you're just extending Float
. If you take a look at Dictionary
it's public struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible
so what you'd be trying to achieve with
extension BeaconID {}
is adding an extension to Dictionary
with specific generic parameters.
What I would expect that you should be able to do is:
typealias BeaconID = Dictionary<Key: String, Value: NSObject>
but that also doesn't compile and that's because in Swift you can't typealias partial types (in other words generic types without specific generic parameter types. See here for more info). A possible workaround for typealiasing generic types which is noted below the answer I linked to is
struct Wrapper<Key: Hashable, Value> {
typealias T = Dictionary<Key, Value>
}
typealias BeaconID = Wrapper<String, NSObject>.T
but even then when you try to extend BeaconID
, you get a compiler warning, which finally gets to the heart of the problem:
"Constrained extension must be declared on the unspecialized generic type 'Dictionary' with constraints specified by a 'where' clause"
Update at the time of Swift 4.2: you can now do this
Example:
typealias KeyedNumbers = [String: Int]
extension KeyedNumbers {
func squaredValue(forKey key: String) -> Int {
return self[key]! * self[key]!
}
}
With that (pretty useless) extension in place, you can do this:
let pairs = ["two": 2, "three": 3]
print("2 squared =", pairs.squaredValue(forKey: "two"))
And it will print
2 squared = 4