🏷️
[Tagged]SwiftのモデルにIDを作る[幽霊型]
Tagged
Taggedで解決できる問題
以下のコードは一見何も問題がないように思えますが、fetchUser
のidにはStringであれば何でも渡せてしまいます。
呼び出しを間違えても、コンパイルエラーにはならないため、気づかない可能性があります。
struct User: Identifiable {
typealias ID = String
let id: ID
let name: String
let age: Int
}
func fetchUser(id: User.ID) -> User
let id = book.id
let user = fetchUser(id: id) // 型は同じだがデータが異なる
Taggedを使った解決方法
typealias ID = Tagged<Self, String>
を宣言します。
import Tagged
struct User: Identifiable {
typealias ID = Tagged<Self, String>
let id: ID
let name: String
let age: Int
}
func fetchUser(id: User.ID) -> User
これにより以下のコードは型が異なるため、コンパイルエラーになり間違いに気づきやすくなります。
let id = map.id
let user = fetchUser(id: id)
Taggedを使わない自前解決方法
モデルに対してネストしたIDを宣言することで型が被らないようにすることができます。
ただ全モデルにIDを作らないといけません。
struct User: Identifiable {
let id: ID
let name: String
let age: Int
struct ID: Hashable {
var value: String
}
}
Discussion