定義
役割:typedef は既存の型に簡潔な別名を付ける構文で、型エイリアスと呼ばれます。Dart 2.13 から全ての型に対応し、それ以前のバージョンでは関数型のみ利用できました。
構文:typedef 別名 = 元の型;
例:typedef IntList = List<int>; と記述すると、以降 List<int> の代わりに IntList を直接記述可能です。
typedef IntList = List<int>;
IntList il = [1, 2, 3];Code language: Dart (dart)
ジェネリック引数に対応
型エイリアスにジェネリックを設定し、複雑な複合型を簡略化できます。
typedef ListMapper<X> = Map<X, List<X>>;Code language: Dart (dart)
ListMapper<String> は Map<String, List<String>> と同じ意味で、コードが簡潔で読みやすくなります。
typedef ListMapper<X> = Map<X, List<X>>;
Map<String, List<String>> m1 = {}; // 長ったらしい記述
ListMapper<String> m2 = {}; // 同じ型で簡潔かつ分かりやすいCode language: Dart (dart)
関数型エイリアス
関数シグネチャにエイリアスを定義し、関数の形式を統一して制限できます。
typedef Compare<T> = int Function(T a, T b);Code language: Dart (dart)
(T, T) → int のシグネチャに適合する関数は全て Compare<T> 型となり、is 演算子で型の一致を確認できます。
typedef Compare<T> = int Function(T a, T b);
int sort(int a, int b) => a - b;
void main() {
assert(sort is Compare<int>); // 判定結果はtrue
}
Code language: Dart (dart)
具体的な実例
// 型エイリアスを定義
typedef IntList = List<int>;
typedef StringMap = Map<String, dynamic>;
void main() {
// エイリアスを直接使用
IntList nums = [10, 20, 30];
StringMap info = {"name": "dart", "version": "2.18"};
print(nums);
print(info);
}Code language: JavaScript (javascript)

// ジェネリックエイリアス:キーがX、値がX型配列のMap
typedef ListMapper<X> = Map<X, List<X>>;
void main() {
// 標準の長い記法
Map<String, List<String>> oldData = {
"fruit": ["apple", "banana"]
};
// typedefによる簡略記法、型は完全同一
ListMapper<String> newData = {
"fruit": ["apple", "banana"]
};
print(oldData);
print(newData);
}Code language: Dart (dart)

// ジェネリック関数エイリアス:引数を2つ(T型)受け取り、整数を返す
typedef Compare<T> = int Function(T a, T b);
// Compare<int> のシグネチャに適合する関数
int intSort(int a, int b) => a - b;
// Compare<String> のシグネチャに適合する関数
int strSort(String a, String b) => a.length - b.length;
void main() {
// 型検証
assert(intSort is Compare<int>);
assert(strSort is Compare<String>);
// 引数として渡して利用
List<int> arr = [5, 1, 3];
arr.sort(intSort);
print(arr); // 出力:[1, 3, 5]
}Code language: Dart (dart)

typedef(型エイリアス)
Previous: Dart ジェネリクス
Next: 完全型システム