Type distinction for Swift

MQTagged

MQTagged provides a Tagged structure which helps differentiating between values of the same type.

Summary

Let’s have an example of a function which authorizes a user based on two string parameters:

func authorize(_ username: String, _ password: String) {
  ...
}

It is possible to call the function with swapped arguments without any compiler warning. Using a typealias also does not solves the issue:

typealias Username = String
typealias Password = String

func authorize(_ username: Username, _ password: Password) {
  ...
}

let username: Username = "user@name.com"
let password: Password = "pa55w0rD"

authorize(username, password)
authorize(password, username) // It's wrong but still compiles.

typealias doesn’t cause compiler warning or error when type names are not matching since resolved type is the same. MQTagged solution to this problem is to use Tag type:

enum UsernameTag {}
enum PasswordTag {}

typealias Username = Tagged<String, UsernameTag>
typealias Password = Tagged<String, PasswordTag>

func authorize(_ username: Username, _ password: Password) {
  ...
}

Now any call with swapped parameters won’t compile.

let username: Username = "user@name.com"
let password: Password = "pa55w0rD"

authorize(username, password)
authorize(password, username) // This won't compile.

Installation

MQTagged can be integrated throught Swift Package Manager. In your Package.swift file add the following dependency:

dependencies: [
  .package(
    url: "https://gitlab.com/miquido/dev/ios/mqtagged.git",
    .upToNextMajor("0.1.0")
  )
]

License

Copyright 2022 Miquido

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

GitHub

View Github