beefon
(Vladislav Alekseev)
1
Why doesn't Swift enforce type matching policy for typealiases? What was the decision behind this?
typealias MeaningfulType = String
func process(value: MeaningfulType) {}
I can now call process with both random String object and MeaningfulType objects, and even though they are actually the same thing, I expected Swift to force type check for me. The reason: I want to be sure only MeaningfulType objects from a specific source are accepted by process(), and any other random string would cause compiler error.
1 Like
beefon
(Vladislav Alekseev)
2
Without this type check I have to introduce a wrapper around String and that looks a bit dirty.
Lantua
3
Type alias is, quite literally, just an alias. It’s as if you just type String wherever you type MeaningfulType.
As you said, you’ll need to write a wrapper around the type you want. It could be troublesome at times, but performance-wise, it’s free.
6 Likes
cukr
4
The feature you want is called newtype in other languages. It was pitched on this forum in the past, you can read these for more insight.
4 Likes
As cukr said, newtype sounds like what you're thinking of. Many folk want it.
The way to get most of the behavior you're after is
struct MeaningfulType {
var value: String
}
My understanding is that the compiler recognizes that there is only one member so it doesn't take any extra space. The only downside is having to reach into MeaningfulType's value member.
4 Likes
Lantua
6
As of Swift 5.1, that can be fixed with @dynamicMemberLookup:
@dynamicMemberLookup
struct MeaningfulValue {
private var value: String
public init(_ value: String) { self.value = value }
public subscript<U>(dynamicMember keyPath: KeyPath<String, U>) -> U {
return value[keyPath: keyPath]
}
public subscript<U>(dynamicMember keyPath: WritableKeyPath<String, U>) -> U {
get { return value[keyPath: keyPath] }
set { value[keyPath: keyPath] = newValue }
}
}
1 Like