はじめに
TypeScriptを学んでて、InterfaceとType Aliasの違いがわからなかったので、まとめてみました。
簡潔にまとめると
- Type Aliasは拡張しにくい
- Interfaceは拡張しやすい
- 開発したものを拡張して使ってもらいたい場合(ライブラリ開発など)は、Interfaceを使うと良い
- アプリ開発は、バグを生みづらいType Aliasを使うと良い
- 基本的には、Case by caseで決める
Type Alias | Interface | |
---|---|---|
用途 | 複数の場所で再利用する 型に名前をつけるため |
オブジェクト・クラス・関数の構造を定義するため |
拡張性 | 同名のtypeを宣言するとエラー | 同名のinterfaceを宣言するとマージされる |
継承 | 継承はできないが、交差型で新しいエイリアスを作る事ができる | extendsによる継承ができる |
使用できる型 | オブジェクトや関数以外のプリミティブ、配列、タプルも宣言可能 | オブジェクトと関数の方のみ宣言できる |
考慮事項 | 拡張しにくい不便さがある | 拡張できることによりバグを生む可能性がある |
いつ使う | アプリ開発ではType Alias | ライブラリ開発ではInterface |
Interfaceの基本用法と宣言のマージ
- Interface宣言子で定義
- Type Aliasと違って「=」は不要
- 同名のinterfaceを宣言すると型が追加(マージ)される
- 宣言のマージ:同じ名前を共有すること複数の宣言を自動的に結合
インターフェースの場合
// 宣言のマージ
interface Bread {
calories: number
}
interface Bread {
type: string
}
const francePan: Bread = {
calories: 350,
type: 'hard', // プロパティがないとエラーになる
}
型エイリアスの場合
type Tamago = {
calories: number
spicyLevel: number
}
type Rice = {
calories: number
gram: number
}
type Oyakodon = Tamago & Rice // 交差型(union)を使う
// OyakodonとRice両方の型を持つ変数を定義
const oyakoDon: Oyakodon = {
calories: 500,
gram: 100,
spicyLevel: 5,
}
Interfaceの拡張
- extendsを使うことで継承したサブインターフェースを作ることができる
- Type Aliasをextendsすることもできる
インターフェースの拡張
interface Book {
page: number
title: string
}
interface Magazine extends Book {
cycle: 'daily' | 'weekly' | 'monthly' | 'yearly'
}
const jump: Magazine = {
cycle: 'weekly',
page: 300,
title: '漫画',
}
インターフェースは型エイリアスも拡張できる
type BookType = {
page: number
title: string
}
interface HandBook extends BookType {
theme: string
}
const cotrip: HandBook = {
page: 120,
theme: '旅行',
title: '旅行雑誌',
}
Interfaceでclassに型を定義できる
インターフェースでクラスに型を定義する
interface Book {
page: number
title: string
}
class Comic implements Book {
page: number
title: string
constructor(page: number, title: string, private publishYear: string) {
this.page = page
this.title = title
}
getPublishYear() {
return this.title + 'が発売されたのは' + this.publishYear + '年です。'
}
}