Typealias はSwiftの宣言で、新しい型を定義せずに既存の型に代替名を作成します。エイリアスはコンパイル時に元の型と完全に同等です — コンパイラはtypealiasが使用されているすべての場所で元の型を置き換えます。Swift Language Guide(2025)によると、typealiasは長いシグネチャの短縮、プロトコル内のassociatedtypeによる内部型の抽象化、複雑なジェネリックパラメータの簡略化に使用されます。型ラッパーとは異なり、typealiasは型安全性を追加しません — これは単なるエイリアスであり、型システムによって区別されません。
主要ポイント
typealias NewName = ExistingType — 任意のレベルで宣言可能(グローバル、ローカル、型の内部)typealias Result = Swift.Result<Data, Error>typealias Handler = (Int) -> VoidTypealias はSwiftの宣言で、既存の型に代替名を導入します。typealiasを宣言した後、新しい名前は元の型が期待される場所で使用できます — コンパイラはそれらを同一と見なします。Typealiasは意味的な分離を追加しません。UserID型(Stringのtypealias)の値は、エラーなくStringを期待する関数に渡せます。
Typealiasの主な目的は、長い名前の短縮、型の目的の文書化、具体的な実装の抽象化です。例えば、typealias JSON = [String: Any]は辞書がJSON構造として使用されることを明示し、typealias Completion = (Result<Data, Error>) -> Voidは複雑なクロージャシグネチャを読みやすい型に変換します。
Swift.org(2025)によると、typealiasは標準ライブラリで広く使用されています。例えば、StringはStringのtypealiasです(特殊化されたArray<Character>)。ただし、現代のSwiftバージョンではこの実装は隠されています。Voidは空タプル()のtypealiasで、関数シグネチャをより読みやすくします。
型のセマンティクスを文書化するためにtypealiasを使用してください。ただし、同じ基本型の異なる概念の混同を防ぐものではないことを覚えておいてください。型安全な分離には、ラッパー(struct wrapper)を使用してください。
Typealiasはキーワードtypealiasで宣言され、その後に新しい名前、等号、既存の型が続きます。基本形式:
typealias Name = ExistingType
typealias UserID = Int
typealias JSONDictionary = [String: Any]
Typealiasのスコープは宣言された場所によって決まります:
| レベル | 例 | 可視性 |
|---|---|---|
| グローバル | typealias Name = String | モジュール全体(アクセス制御の対象) |
| 型の内部 | struct User { typealias ID = Int } | User.ID — 型を通じてアクセス可能 |
| 関数の内部 | func f() { typealias Local = Int } | 関数内のみ |
| プロトコルの内部 | protocol P { associatedtype T } | 準拠時に指定 |
型の内部のTypealias(例:User.ID)は関連するエイリアスをグループ化する一般的なパターンです。これにより名前空間が改善されます。Order.IDとUser.IDは両方ともIntですが、異なる概念として読まれます。ネストされたtypealiasへのアクセスはUser.IDを介して、または型がわかっている場合はドット記法で行います。
Typealiasの最も一般的な使用法の1つは、クロージャシグネチャの簡略化です。Swiftのクロージャ型は、特にOptionalやジェネリックパラメータがある場合に扱いにくくなることがあります。Typealiasは(Data?, Error?) -> Voidを読みやすいFetchResultHandlerに変換します:
typealias FetchResultHandler = (Data?, Error?) -> Void
func fetchUser(id: Int, completion: FetchResultHandler) {
// network request
completion(data, nil)
}
Ray Wenderlich Style Guideによると、クロージャのtypealiasはメソッドシグネチャの可読性を向上させます。特に委譲プロトコルやコールバックパターンで効果的です。ただし、過剰なエイリアスは避けてください。クロージャが1か所でのみ使用される場合は、インラインで宣言できます。
Swift標準ライブラリはこのアプローチを積極的に使用しています。例えば、DispatchQueue.WorkItemはDispatchWorkItemのtypealiasですが、外部からは別の型のように見えます。クロージャのtypealiasは可読性のツールです — 使いすぎないでください。モジュールあたり3〜5個のクロージャエイリアスが妥当な制限です。
Typealiasはジェネリックパラメータを含めることができ、ジェネリック型の特殊化バージョンを作成します。これはResult、Publisher、および標準ライブラリやCombineの他のジェネリック型を扱う場合に特に便利です:
typealias FetchResult = Result<Data, Error>
typealias AnyPublisherOfData = AnyPublisher<Data, Error>
func loadData() -> FetchResult {
// data loading
}
元の型に転送されるカスタムジェネリックパラメータを持つtypealiasを作成することもできます:
typealias NetworkResult<T> = Result<T, NetworkError>
func fetchUser() -> NetworkResult<User> {
// ...
}
重要なルール: typealiasは新しいジェネリック制約(where句)を追加できません — パラメータを元の型に転送するだけです。追加の制約が必要な場合は、ジェネリックstructまたはclassを作成してください。Swift by Sundell(2024)によると、ジェネリックを使用したtypealiasは、Combine、Result、async/awaitを多用するプロジェクトで繰り返しシグネチャを短縮する理想的な方法です。
Associatedtype はプロトコル内で宣言されるtypealiasで、関連型を定義します。通常のtypealiasとは異なり、associatedtypeは宣言時に特定の型に結びつきません — プロトコルに準拠する各型によって指定されます:
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
}
struct IntBox: Container {
typealias Item = Int
// implementation
}
struct StringBox: Container {
typealias Item = String
// implementation
}
Associatedtypeは、宣言時に具体的な型を指定することなく、プロトコルにジェネリック型の柔軟性を与えます。これは多くのSwiftパターンの基盤です。Collection(Element)、IteratorProtocol(Element)、Identifiable(ID)。コンパイラは実装から自動的にassociatedtypeを推論できるため、明示的なtypealias Item = Intはしばしば省略されます — SwiftはメソッドappendのパラメータからItemをIntとして推論します。
Swift Evolution SE-0195(2022)によると、associatedtypeを含むプロトコルを扱うために不透明結果型(some Container)が導入されました — これにより、そのようなプロトコルを変数型として使用できなかったPAT(associated typesを持つプロトコル)の問題が解決されました。
主な違い: typealiasは既存の型の単なる別名ですが、ラッパー(wrapper)は元の型から意味的に分離された新しい型です。typealias UserID = Intと宣言すると、UserIDとIntは交換可能です — Intを期待する関数はエラーなくUserIDを受け入れます。
ラッパーはstructを介して作成され、真の型安全性を提供します:
struct UserID: RawRepresentable {
let rawValue: Int
}
struct OrderID: RawRepresentable {
let rawValue: Int
}
// Compilation error: cannot pass OrderID where UserID is expected
Point-Free(2025)によると、異なる概念が同じ基本型(UserID vs OrderID)で表現される場合、ラッパーが推奨されます。Typealiasは、分離なしの可読性が目標の場合に正当化されます:長い名前の短縮、セマンティクスの文書化、associatedtypeによる実装の抽象化。読みやすさのためにtypealiasを、型安全性のためにラッパーを選択してください。
よくある質問
Typealiasは特定の既存の型のエイリアスです。Associatedtypeはプロトコル内で宣言され、プロトコルに準拠する各型によって指定されます — 異なる型は同じプロトコルに異なるassociatedtypeを使用できます。
いいえ、typealiasは単なる代替名です。コンパイラはコンパイル時にそれを元の型に置き換えます。新しい意味的に分離された型を作成するには、structラッパーまたはrawValueを持つenumを使用してください。
はい、typealiasはジェネリックパラメータを含めることができます: typealias Result<T> = Swift.Result<T, Error>。ジェネリックパラメータは元の型に転送されます。where制約は追加できません — その場合はジェネリックstructを使用してください。
任意のレベルで: グローバル(ファイル内)、型の内部(struct/class/enum)、関数の内部、プロトコルの内部(associatedtypeとして)。スコープは宣言場所によって決まります — グローバルなtypealiasはモジュール全体で表示可能、ローカルなものはそのスコープ内のみです。
元の型との交換可能性が安全な場合、長い名前の短縮とセマンティクスの文書化にtypealiasを選択してください。同じ基本型(UserID vs ProductID)の異なる概念の偶発的な混同を防ぐ必要がある場合は、ラッパー(struct)を選択してください。
まとめ
typealias NewName = ExistingType、スコープ — グローバル、型の内部、関数の内部typealias Handler = (Int) -> Voidターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。