mizkog-logo

Web制作の備忘録

HomeZennPortfolio

InterfaceとType Aliasの違い

TypeScript

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に統一した方が一貫性があり、簡潔で記述も短くスッキリしている。