InterfaceとType Aliasの違い
Type Aliasの書き方
type Foo = {
a: number;
};
const foo: Foo = {
a: 1,
};
Interfaceの書き方
interface Foo {
a: number;
}
const foo: Foo = {
a: 1,
};
InterfaceとType Aliasの違い
①宣言できる型の違い
Interfaceは宣言できるものが辞書型としてのオブジェクト。
あくまで辞書型としてのオブジェクトに対して型宣言するもの。
Type Aliasは上記に限らず、オブジェクト以外のものに対しても型宣言できる。
②open-endedに準拠しているかどうかの違い
Type Aliasはopen-endedに準拠していないので、同じ名前の宣言があるとエラーが出る。
※open-endedとは同じ名前で宣言があった時に自動的にマージされる性質のこと。
③継承(型の拡張)方法の違い
Interface
Interfaceは以下のようにextens
を用いる
interface Foo {
a: number;
}
interface Bar extends Foo {
b: number;
}
const foo: Bar = {
a: 1,
b: 2,
};
Type Alias
Type Aliasは以下のようにIntersection Types
を用いる。
type Foo = {
a: number;
}
type Bar = Foo & {
b: number;
}
const foo: Bar = {
a: 1,
b: 2,
};
④プロパティのオーバーライドの挙動の違い
Interface
例としてプロパティをnumberからstringへオーバーライドした際には、
宣言の時点で、型の互換性が無いというエラーが出るため、予期せぬ値を事前に防ぐことが出来る。
Type Alias
例としてプロパティをnumberからstringへオーバーライドした際には、
string かつ numberは成り立たないのでneverとなる。
⑤Mapped Typesが使用できるかどうかの違い
Interface
使用できない。
Type Alias
使用できる。
Mapped Typesとは
他の型をもとに新しい方を作成するための方法
type Animals = "dog" | "cat";
type foo = {
dog: number;
cat: number;
}
のようにAnimalsが増えれば増えるほど手動で増やしていくことは大変なので、
以下のようにMapped Typesを用いると自動的に作成することが出来る。
type Animals = "dog" | "cat";
type foo = {
[key in Animals]: number;
}
// 以下の結果となる
// type foo = {
// dog: number;
// cat: number;
// }
InterfaceとType Aliasどちらを使用するべきか
結論としては、どちらでも良いがType Aliasに統一した方がおすすめ。
TypeScriptの公式にも「ほとんどの場合、個人の好みに応じて選ぶことができます」と記述されている。
また、公式としてはInterfaceを使用してType Aliasでないと出来ないことがあればType Aliasを使用するよう記述もされているが、
InterfaceとType Aliasのメリット・デメリットで考えるとType Aliasの方がメリットが多い部分がある。
TypeScript Everyday Types
Type Aliasの方がメリットが多い部分
- プリミティブ型や配列を使用できる
- open-endedに準拠していないので、同じ名前の宣言があるとエラーを出してくれる
- オーバーライドに関してはInterfaceの方が優秀ではあるが、そういった自体がそこまで多くなく、どの道、コンパイルエラーは出してくれるのであまり変わらない
- Mapped Typesを使用できる
Type Aliasに統一した方が一貫性があり、簡潔で記述も短くスッキリしている。