I have a typealias:
typealias BeaconId = [String: NSObject]
I'd like to extend it by doing something like:
extension BeaconId {}
But this throws a compile error:
Constrained extension must be declared on the unspecialized generic type 'Dictionary' with constraints specified by a 'where' clause
So I end up doing:
extension Dictionary where Key: StringLiteralConvertible, Value: NSObject {}
Is there a cleaner way to do this?
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"