はじめに
本記事は TypeScript Handbook の Advanced Types に書かれているものをベースに、説明されている内容をこういう場合はどうなるのかといったことを付け加えて ちょっとだけ 掘り下げます。完全な翻訳ではなく、若干元の事例を改変しています。
今回は Type Aliases について掘り下げます。
その1 Type Guards and Differentiating Types は こちら
その2 Nullable types は こちら
その4 String Literal Types / Numeric Literal Types は こちら
その5 Discriminated Unions は こちら
その6 Index types は こちら
その7 Mapped types は こちら
Type Aliases
型にエイリアスをつけることができます。どの型に対しても使えます。
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === 'string') {
return n;
} else {
return n();
}
}
エイリアスをつけることで新しい型が作られるわけではなく、その型を参照する新しい名前が作成されます。 primitive に対してエイリアスをつけることでとりわけ便利になることはないですが、ドキュメントの一種として使用することができます。
interface と同様にエイリアスにもジェネリクスが使えます。
type Container<T> = { value: T };
エイリアスは自身のプロパティ内でも利用することができます。
type Tree<T> = {
value: T;
left: Tree<T>;
right: Tree<T>;
}
交差型と共に利用することで、面白い型を作ることができます。
type LinkedList<T> = T & { next: LinkedList<T> };
interface Person {
name: string;
}
var people: LinkedList<Person>;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;
ただし、エイリアスの宣言の右側に直接用いることはできません。
type Yikes = Array<Yikes>; // コンパイルエラー
Interfaces vs. Type Aliases
エイリアスとインターフェイスは似ていますが、若干異なります。
その差異について、 Handbook に三つその違いが記載されているのですが、その内二つが 間違っています 。
間違いの詳細については Interface vs Type alias in TypeScript 2.7
という記事に詳しく書かれているので省きますが、簡単にまとめると、
- エラーメッセージにエイリアスは表示されないし、エディタのポップアップにも表示されない -> エイリアスが表示される
- エイリアスを継承したり実装することはできない -> エイリアスを実装したインターフェイスやクラスの作成は可能
- ユニオンやタプルにはエイリアスを使います -> その通り
になります。
詳細な違いについては、 TypeScriptのInterfaceとType aliasの比較
という記事が参考になります。
まとめ
インターフェイスとエイリアスの違いについて正しく理解し、エイリアスを上手に使うと色々捗りそう。
Handbook は結構いい加減... ドキュメントってやっぱりメンテされない...