【TS】型エイリアス(type)とインターフェイスの違いとは!!!
これは何?
今、フロントの開発力をつけるためにオライリーの「プログラミング Typescript」を読み進めながらTypescriptを勉強しております。
その際に、Typescriptの中で出てくる型エイリアス(type)とインターフェイスの違いが勉強になったため備忘録としてまとめました!
そもそも、型エイリアス(type)とインターフェイスって何?
型エイリアス(type)は、型に対して名前をつけることができます。
以下のように type
をつけて宣言し、型に名前をつけます。
type Person = {
name: string
age: number
}
一方、インターフェイス(interface)も型エイリアスと同様に型に名前をつける方法の1つになります。
インターフェイスは以下のように、interface
をつけて宣言し、型に名前をつけます。
interface Person {
name: string
age: number
}
違いは何?
小さい違いになりますが、以下の3つがあります
- 型エイリアスは右辺に形状以外に型の式が定義できる。
- インターフェイスを拡張する場合、拡張元が拡張先に割り当て可能かどうかチェックする
- intefaceには、宣言のマージと呼ばれる機能がある。
上記の3つの違いを1つ1つみていきます!
型エイリアスは右辺に形状以外に型の式が定義できる
型エイリアスは、形状以外にも型の式を定義でき、インターフェイスより汎用的に型を定義できます。
型の式
とは、型と「&」や「|」のような型演算子になります。
例えば以下のような型は、インターフェイスでは定義できません。
type TypeA = number
type TypeB = string | number
type TypeA = string[]
インターフェイスを拡張する場合、拡張元が拡張先に割り当て可能かどうかチェックをする
インターフェイスは、以下のように拡張する場合、拡張元が拡張先に割り当て可能かどうかのチェックが行われ、割り当てができない場合コンパイル時にエラーが吐かれます。
interface TypeA {
name: string
age: number
}
// エラーになる
// Types of property 'name' are incompatible.
interface TypeB extends TypeA {
name: string | number
age: number
}
一方、型エイリアスの場合は、拡張元の型と拡張先の型が結合されて、うまい具合に上書かれるためエラーにはなりません。
type TypeA = {
name: string
age: number
}
// エラーにならない
// nameの型が、`string`から`string | number`に上書かれる。
type TypeB = TypeA & {
name: string | number
age: number
}
intefaceは同じスコープ内で同じ名前が複数存在する場合は、自動的にマージされる
インターフェイスには、宣言のマージと呼ばれる機能があり、同じスコープ内で同じ名前が複数ある場合、自動的にマージされるようになっています。
interface Type {
name: string
}
interface Type {
name: string
age: number
}
interface Type {
address: string
}
// エラーにならず、Typeの型は宣言のマージによりマージされ、
// `name: string`と`age: number`、`address: string`を持つオブジェクトの型になる
一方、型エイリアスでは同じスコープ内で同じ名前が複数ある場合、コンパイル時にエラーになります。
// Duplicate identifier 'Type'. とエラーが出る
type Type = {
name: string
}
// Duplicate identifier 'Type'. とエラーが出る
type Type = {
name: string
age: number
}
まとめ
型エイリアスとインターフェイスはできることが似ているが、3つ異なる部分があります
- 型エイリアスは右辺に形状以外に型の式が定義できる。
- インターフェイスを拡張する場合、拡張元が拡張先に割り当て可能かどうかチェックする
- intefaceには、宣言のマージと呼ばれる機能がある。
上記の違いを踏まえて、今後、Typescriptの開発をしていく中で、どういうケースでどっちを使うべきかを意識しながら、自分なりのベストプラクティスを見つけていきたいと思います!
Discussion