この記事ではTypeScriptのtypeとinterfaceの違いについて、実践的な例を交えて解説していきます。
これから、結論、TypeScriptのtypeの説明、TypeScriptのinterfaceの説明、typeとinterfaceの違い、どちらを使うべきか、という順番でお話しします!
TypeScriptのtypeとinterfaceはどちらも 型を定義するための機能 です。
似ている機能だからこそどちらを使えばいいのか悩みますよね。
それぞれ使い方や適用範囲が異なりますが、基本的にはどちらをつかっても問題はない と思います。
個人的にはあとから勝手に型情報が変更されたりしないtypeの方が好みだったりします...!
それでは、まずはTypeScriptのtypeについて説明していきます。
TypeScriptのtypeは 型エイリアス とも呼ばれ、新しい型を定義する 際に使います。
例えば次のようにtypeを使って、新しい型を定義できます。
type User = {
name: string;
age: number;
};
上記のコードでは name
プロパティが文字列型、age
プロパティが数値型のオブジェクトを表す新しい型 User
を定義しています。
また、typeは 既存の型を組み合わせて新しい型を作る こともできます!
type Animal = "Dog" | "Cat" | "Bird";
この例では Animal
という新しい型を定義して、この型には Dog
、Cat
、Bird
のいずれかの値を入れることができます。
指定した値しか入れることができない新しい型、ということですね。
さらに、タプル型を使って 要素数が固定された配列型 を定義することができます。
type Point = [number, number];
この例では Point
という新しい型を定義して、この型は2つの数値要素からなる配列(タプル)を表します。
2つ以上の数値を代入することができない配列型ということですね。
TypeScriptのinterfaceについてはどうでしょうか?
TypeScriptのinterfaceは オブジェクトの型を定義する 際に使います。
例えば、次のようにinterfaceを使ってオブジェクトの型を定義できます。
interface User {
name: string;
age: number;
}
先ほどのtypeの例と同じように、name
プロパティが文字列型、age
プロパティが数値型のオブジェクトを表す型 User
を定義しています。
比べてみるとtypeとは書き方が少し違いますよね。
また、interfaceは 継承を使って他のinterfaceから型を引き継ぐ ことができます。
これによって既存の型を再利用して、新しい型を定義することが容易になります。
interface Animal {
species: string;
sound: string;
}
interface Dog extends Animal {
breed: string;
}
上記のコード例では Animal
インターフェースを定義した後、Dog
インターフェースで Animal
を継承しています。Dog
インターフェースは Animal
のプロパティに加えて breed
プロパティも持っています。
interfaceは継承で他のinterfaceから型を引き継げますが、実はtypeとinterfaceはどちらも ユーティリティ型 という型を使用することで同様に既存の型を引き継いで使用することもできます。
これについては以下の記事で詳しくまとめています!
それでは、typeとinterfaceの違いを具体的なコードを使って詳細に説明します。
interfaceの説明でもご紹介したようにinterfaceは既存のオブジェクトの型を引き継いで新しい型定義を作成することができます。
interface Vehicle {
wheels: number;
speed: number;
}
interface Car extends Vehicle {
doors: number;
}
interface Motorcycle extends Vehicle {
type: 'cruiser' | 'sport' | 'dirt';
}
const myCar: Car = {
wheels: 4,
speed: 120,
doors: 4,
};
const myMotorcycle: Motorcycle = {
wheels: 2,
speed: 180,
type: 'sport',
};
このコード例では最初に Vehicle
インターフェースを定義し、その後 Car
と Motorcycle
インターフェースで Vehicle
を継承しています。
Car
インターフェースは Vehicle
のプロパティに加えて、doors
プロパティを持っています。
一方、Motorcycle
インターフェースは Vehicle
のプロパティに加えて type
プロパティを持っています。
同名のインターフェースを複数回定義することでそれらが自動的にマージ(1つにまとめる)されます。
interface User {
name: string;
}
interface User {
age: number;
}
// 結果的にUserインターフェースは以下のようになります
// interface User {
// name: string;
// age: number;
// }
この例では User
インターフェースが二度宣言されていますが、TypeScriptは自動的にマージして name
と age
のプロパティを持つ User
インターフェースとして定義されます。
typeはinterfaceのように継承を使うことはできませんが、ユーティリティ型を使うことで既存の型定義を再利用して新しい型を定義することができます!
type User = {
name: string;
age: number;
};
type PartialUser = Partial<User>;
// 結果的にPartialUser型は以下のようになります
// type PartialUser = {
// name?: string;
// age?: number;
// }
この例では User
型を定義した後、Partial
ユーティリティ型を使って PartialUser
型を定義しています。
PartialUser
は最初に定義した User
と比較して name
と age
プロパティが任意項目となっています。name?: string
のように、 ?
がつくことで任意項目であることを意味しているわけですね。
typeでは ジェネリクス という型を使用することで柔軟に型定義をすることができます。
最初は少し難しく感じることがあるかと思いますが、使いこなすととても便利な機能です!
type ApiResponse<T> = {
status: 'success' | 'error';
data?: T;
message?: string;
}
type UserData = {
id: number;
name: string;
}
const response: ApiResponse<UserData> = {
status: 'success',
data: {
id: 1,
name: 'Alice',
},
};
このコードでは、ジェネリクス型を用いて ApiResponse
型を定義しています。
type ApiResponse<T>
と書くことでこれはジェネリクス型であることを宣言しているわけですね。
この ApiResponse
型は呼び出すときに ApiResponse<UserData>
のように <>
内の T
に型を書くことで、自動的に data
プロパティの型に指定した型定義が使用されます。
これにより ApiResponse
型は任意の型 T
を持つことができるため、非常に柔軟な型定義ができます!
これまで紹介したように、TypeScriptのtypeとinterfaceはどちらも型を定義するための機能ですが使い方や特徴が少し違います。
interfaceは オブジェクトの型定義や継承 をサポートしているため、拡張性と再利用性が高くなるなります。
一方、typeは ユーティリティ型を使って型を拡張 することができ、ジェネリクスを使うことで柔軟に型を定義 することが可能です。
結果として、typeとinterfaceはどちらを使っても問題ありません!
現在のプロジェクトで使用している方に統一したり、個人的に使いやすいと感じたほうを使うのが良いと思います。
ぜひこの記事の内容を今後のプログラミングに役立ててくださいね!
TypeScriptの短絡評価の使い方「&&」「||」「??」の解説
TypeScriptのタイマー関数setTimeoutとsetIntervalの使い方
TypeScriptの多次元配列の使い方についてわかりやすく解説
TypeScriptでのタプルの使い方と実践テクニックを解説
TypeScriptのimport typeをわかりやすく解説
TypeScriptの配列やオブジェクトのソート完全ガイド
TypeScriptコメントアウトの使い方 完全ガイド
TypeScriptのオブジェクトとプロパティの存在チェック完全ガイド
TypeScriptで即時関数を使う方法を解説!基本から実践的な使い方まで