はじめに
以前、初めてTypeScriptを実務で使用した際に、Interface(インターフェース)とtype(型エイリアス)
どちらを使うべきか迷うことがあったので、知見を今更ながらまとめます。
Because an interface more closely maps how JavaScript objects work by being open to extension, we recommend using an interface over a type alias when possible.
ref:https://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases
公式ドキュメントにインターフェース(interface) が推奨されています。
理由は、インターフェースがJavaScriptオブジェクトの動作により近いからです。具体的には、インターフェースは拡張可能であり、同じ名前のインターフェースを複数回宣言しても、それらがマージされます。
ただ、これだけだいまいちピンと来ないと思うので次の章でサンプルコードを出していきます。
Interface と type の違いについて
拡張性について、インターフェースは拡張可能であり、同じ名前のインターフェースを複数回宣言しても、それらがマージされます。
サンプルコードを書いていきましょう。
同名のものを宣言
interface
interface Cat {
name: string
}
interface Cat {
age: number
}
上記のコードは問題なく動作します。実質的には以下と同じです。
interface Cat {
name: string
age: number
}
さあ、typeはどうでしょうか。 このような拡張は使用できません。
type
type Cat = { // 識別子 'Cat' が重複しています。
name: string
}
type Cat = { // 識別子 'Cat' が重複しています。
age: number
}
継承
原則、インターフェースは継承できますが、型エイリアスは継承できません。
interface
interface Animal {
name: string
}
interface Cat extends Animal {
age: number
}
上記のように定義することによって、
interface Cat {
name: string
age: number
}
と同じ意味になります。
型エイリアスでは継承は行えませんが、&
演算子を使用することで、複数の型を結合することができます。
type
type Animal = {
name: string
}
type Cat = Animal & {
age: number
}
継承もそうですし、マージできない問題についても、上記のように型エイリアスを使用することで解決自体はできそうです。
おわりに
正直いって、Interface
でやりたいことはtype
で出来ることが多いですし、どちらを使っても問題ないと思います。
プロジェクトの方針、チームの方針に合わせて使い分けるのが良いと思います。
オブジェクト指向 プログラミング になじみがある方は、Interface
の方が使いやすいかもしれません。
また、歴史的に見るとInterface
は初めからあるもので、type
は後から追加されたもので
type
は できないことが多かったので、以前は Interface
を使う人が多かったようです。
Googleが公開している Interface vs type alias ではオブジェクト型に関してはInterfaceを使うことを推奨されています。
この記事が、Interface と type どちらを使うべきか迷っている方の参考になれば幸いです。
参照