これらのステートメント(インターフェイスとタイプ)の違いは何ですか?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
これらのステートメント(インターフェイスとタイプ)の違いは何ですか?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
回答:
TypeScript言語仕様に従って:
常に名前付きオブジェクトタイプを導入するインターフェイス宣言とは異なり、タイプエイリアス宣言は、プリミティブ、ユニオン、およびインターセクションタイプを含むあらゆる種類のタイプの名前を導入できます。
仕様はさらに言及し続けます:
インターフェイスタイプには、オブジェクトタイプリテラルのタイプエイリアスと多くの類似点がありますが、インターフェイスタイプはより多くの機能を提供するため、タイプエイリアスよりも一般的に推奨されます。たとえば、インターフェースタイプ
interface Point { x: number; y: number; }
タイプエイリアスとして書くことができます
type Point = { x: number; y: number; };
ただし、これを行うと、次の機能が失われます。
インターフェイスはextendsまたはimplements句で名前を付けることができますが、オブジェクトタイプリテラルのタイプエイリアスはTS 2.7以降はtrueになりません。- インターフェイスは複数の宣言をマージできますが、オブジェクトタイプリテラルのタイプエイリアスはできません。
interface Point { x: number; } interface Point { y: number; }
現在の回答と公式ドキュメントは古くなっています。TypeScriptの初心者にとって、使用されている用語は例がなければ明確になりません。以下は、最新の違いのリストです。
どちらも、オブジェクトまたは関数のシグネチャの形状を記述するために使用できます。ただし、構文は異なります。
インターフェース
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
タイプエイリアス
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
インターフェイスとは異なり、型エイリアスは、プリミティブ、共用体、タプルなどの他の型にも使用できます。
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
どちらも拡張できますが、構文は異なります。さらに、インターフェイスとタイプエイリアスは相互に排他的ではないことに注意してください。インターフェイスは型エイリアスを拡張でき、その逆も可能です。
インターフェースはインターフェースを拡張します
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
型エイリアスは型エイリアスを拡張します
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
インターフェイスは型エイリアスを拡張します
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
型エイリアスがインターフェースを拡張
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
クラスは、インターフェースまたは型エイリアスを、まったく同じ方法で実装できます。ただし、クラスとインターフェースは静的なブループリントと見なされます。したがって、ユニオン型を指定する型エイリアスを実装/拡張することはできません。
interface Point {
x: number;
y: number;
}
class SomePoint implements Point {
x = 1;
y = 2;
}
type Point2 = {
x: number;
y: number;
};
class SomePoint2 implements Point2 {
x = 1;
y = 2;
}
type PartialPoint = { x: number; } | { y: number; };
// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
x = 1;
y = 2;
}
型エイリアスとは異なり、インターフェイスは複数回定義でき、単一のインターフェイスとして扱われます(すべての宣言のメンバーがマージされます)。
// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }
const point: Point = { x: 1, y: 2 };
type
かinterface
?どちらを使用するべきか、まだ混乱しています。
type
特定の制限付きでを使用して再帰型を定義できます(TypeScript 3.7以降では、これらの制限もなくなりました)。インターフェイスは型を拡張できます。クラスは型を実装できます。さらに、データをテーブルのスクリーンショットとして表示すると、視覚障害のある人はデータに完全にアクセスできなくなります。
https://www.typescriptlang.org/docs/handbook/advanced-types.html
1つの違いは、インターフェースはどこでも使用される新しい名前を作成することです。タイプエイリアスは新しい名前を作成しません—たとえば、エラーメッセージはエイリアス名を使用しません。
//オブジェクトのツリー構造を作成します。交差(&)がないため、インターフェースで同じことを行うことはできません
type Tree<T> = T & { parent: Tree<T> };
//変数を制限して、いくつかの値のみを割り当てるように入力します。インターフェイスにユニオン(|)がありません
type Choise = "A" | "B" | "C";
//型のおかげで、条件付きメカニズムのおかげでNonNullable型を宣言できます。
type NonNullable<T> = T extends null | undefined ? never : T;
// OOPのインターフェイスを使用し、「実装」を使用してオブジェクト/クラスのスケルトンを定義できます
interface IUser {
user: string;
password: string;
login: (user: string, password: string) => boolean;
}
class User implements IUser {
user = "user1"
password = "password1"
login(user: string, password: string) {
return (user == user && password == password)
}
}
//他のインターフェースでインターフェースを拡張できます
interface IMyObject {
label: string,
}
interface IMyObjectWithSize extends IMyObject{
size?: number
}
すでに提供されている見事な答えに加えて、型とインターフェイスの拡張に関しては、顕著な違いがあります。私は最近、インターフェースが機能しないいくつかのケースに遭遇しました:
ドキュメントは説明しました
- 1つの違いは、インターフェースはどこでも使用される新しい名前を作成することです。タイプエイリアスは新しい名前を作成しません。たとえば、エラーメッセージはエイリアス名を使用しません。古いバージョンのTypeScriptでは、タイプエイリアスは拡張または実装できませんでした(他のタイプを拡張/実装することもできません)。バージョン2.7以降、新しい交差タイプを作成することでタイプエイリアスを拡張できます
- 一方、インターフェースで形状を表現できず、共用体またはタプル型を使用する必要がある場合は、通常、型エイリアスが適しています。