💭
TypeScriptにおけるtypeとinterfaceの違い
TypeScript において、型を定義するのにはtype
キーワードを使う
Type Alias
とinterface
キーワードを使うInterface
の
2 種類があります。その違いについて、ざっとまとめてみました。
定義方法
Type Script
// Type Alias
type Foo = {
a: number;
b: string;
}
//Interface
interface Foo {
a: number,
b:string,
}
interface は宣言のみで type は代入になります。
無名で作られた方に参照のため別名を与えるということをやっています。
interface はブロック{}で終わる文なのでセミコロンが不要になります。
型の定義方法はとても似ていますが、いくつか違いがあります。
継承
interface
はinterface
とtype
を継承することができます。
TypeScript
type Foo = {
a: string;
};
interface Bar extends Foo {
b: number;
}
const Bas: Bar = {
a: "foo",
b: 1,
};
type
は継承できませんが変わりに&
を使用することで、
継承に似たことを実現できます。
TyepScript
type Foo = {
a: string;
};
type Bar = Foo & {
b: number;
};
const Bas: Bar = {
a: "foo",
b: 1,
};
上書き
interface
は上書きをすると継承元の型が上書きされます。
TypeScript
interface User1 {
name: string;
hobby: {
movie: string;
};
age: number;
}
interface User2 extends User1 {
name: string;
hobby: {
movie: string;
sports: string;
};
}
//最終的な型定義
interface User2 {
name: string;
hobby: {
movie:string;
sports:string;
};
age:number
}
ただし、元の型に代入できるものではないと上書きできません。
TypeScript
interface User1 {
name: string;
}
interface User2 extends User1 {
name:number;
//エラー タイプ number はタイプ string に代入できません
}
一方 type では上書きにはならず交差型が適用されます。
先程の型に代入できるものではない場合でもエラーにならず
never 型となります。
TypeScript
type User1 = {
name: string;
hobby: {
movie: string;
};
age: number;
};
type User2 = User1 & {
name: number;
hobby: {
movie: string;
sports: string;
};
};
//最終的な型定義
type User2 = {
name: never; //エラーではなくnever型になる
hobby: {
movie:string;
sports:string;
};
age:number
}
同名を定義
interface
は同名を定義できます。
しかし、先程と同様に元の型に代入できるものではないと
エラーになります。
TypeScript
interface Foo {
bar: string;
bas: number;
}
interface Foo {
bar: number; //エラー
//プロパティbarはstring型である必要がありますが
//number型を指定しています。
}
type
はそもそも同名のものを複数定義できません。
TypeScript
type Foo = {
bar: string;
bas: number;
}
type Foo = {
bar: string; //エラー
//Fooが重複しています
}
結局どっちを使えばいいの!
結論から言うとプロジェクトに合わせるが1番です。
初学者の僕からしたらtype
の方が使いやすいと感じました!
もっと細かい違いがあると思うので勉強していきます。
Discussion