Type enforcing for type aliases

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

Without this type check I have to introduce a wrapper around String and that looks a bit dirty.

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.


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.


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.


As of Swift 5.1, that can be fixed with @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