Was ist der Unterschied zwischen diesen Anweisungen (Schnittstelle vs Typ)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Was ist der Unterschied zwischen diesen Anweisungen (Schnittstelle vs Typ)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Antworten:
Gemäß der TypeScript-Sprachspezifikation :
Im Gegensatz zu einer Schnittstellendeklaration, die immer einen benannten Objekttyp einführt, kann eine Typaliasdeklaration einen Namen für jede Art von Typ einführen, einschließlich Primitiv-, Vereinigungs- und Schnittpunkttypen.
In der Spezifikation wird weiter erwähnt:
Schnittstellentypen haben viele Ähnlichkeiten mit Typaliasen für Objekttypliterale, aber da Schnittstellentypen mehr Funktionen bieten, werden sie im Allgemeinen bevorzugt, um Aliase einzugeben. Zum Beispiel der Schnittstellentyp
interface Point { x: number; y: number; }
könnte als Typalias geschrieben werden
type Point = { x: number; y: number; };
Dies bedeutet jedoch, dass die folgenden Funktionen verloren gehen:
Eine Schnittstelle kann in einer Extended- oder Implementierungsklausel benannt werden, aber ein Typalias für ein Objekttypliteral kannseit TS 2.7nichtmehr wahr sein.- Eine Schnittstelle kann mehrere zusammengeführte Deklarationen haben , ein Typalias für ein Objekttypliteral jedoch nicht.
interface Point { x: number; } interface Point { y: number; }
extends or implements
ist nicht mehr der Fall. Typ kann erweitert und implementiert werden durch a class
. Hier ist ein Beispiel typescriptlang.org/play/...
Die aktuellen Antworten und die offizielle Dokumentation sind veraltet. Und für diejenigen, die neu in TypeScript sind, ist die verwendete Terminologie ohne Beispiele nicht klar. Nachfolgend finden Sie eine Liste der aktuellen Unterschiede.
Beide können verwendet werden, um die Form eines Objekts oder eine Funktionssignatur zu beschreiben. Die Syntax ist jedoch unterschiedlich.
Schnittstelle
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
Geben Sie einen Alias ein
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
Im Gegensatz zu einer Schnittstelle kann der Typalias auch für andere Typen wie Grundelemente, Vereinigungen und Tupel verwendet werden.
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
Beide können erweitert werden, aber auch hier unterscheidet sich die Syntax. Beachten Sie außerdem, dass sich ein Schnittstellen- und Typalias nicht gegenseitig ausschließen. Eine Schnittstelle kann einen Typalias erweitern und umgekehrt.
Schnittstelle erweitert Schnittstelle
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Typalias erweitert Typalias
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
Die Schnittstelle erweitert den Typalias
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
Der Typ-Alias erweitert die Schnittstelle
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
Eine Klasse kann eine Schnittstelle oder einen Typalias auf dieselbe Weise implementieren. Beachten Sie jedoch, dass eine Klasse und eine Schnittstelle als statische Blaupausen betrachtet werden. Daher können sie keinen Typalias implementieren / erweitern, der einen Vereinigungstyp benennt.
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;
}
Im Gegensatz zu einem Typalias kann eine Schnittstelle mehrfach definiert werden und wird als eine einzige Schnittstelle behandelt (wobei Mitglieder aller Deklarationen zusammengeführt werden).
// 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
oder interface
? Ich bin immer noch verwirrt, wann ich das eine oder andere verwenden soll.
type
mit bestimmten Einschränkungen definieren (und ab TypeScript 3.7 sind diese Einschränkungen ebenfalls weg). Schnittstellen können Typen erweitern. Klassen können Typen implementieren. Darüber hinaus ist die Darstellung von Daten als Screenshot einer Tabelle für Personen mit Sehbehinderung völlig unzugänglich.
https://www.typescriptlang.org/docs/handbook/advanced-types.html
Ein Unterschied besteht darin, dass Schnittstellen einen neuen Namen erstellen, der überall verwendet wird. Typ-Aliase erstellen keinen neuen Namen. In Fehlermeldungen wird beispielsweise der Aliasname nicht verwendet.
// eine Baumstruktur für ein Objekt erstellen. Mit der Schnittstelle können Sie nicht dasselbe tun, da keine Schnittmenge (&) vorhanden ist.
type Tree<T> = T & { parent: Tree<T> };
// Typ, um eine Variable so einzuschränken, dass nur wenige Werte zugewiesen werden. Schnittstellen haben keine Union (|)
type Choise = "A" | "B" | "C";
// Dank der Typen können Sie dank eines bedingten Mechanismus den NonNullable-Typ deklarieren.
type NonNullable<T> = T extends null | undefined ? never : T;
// Sie können die Schnittstelle für OOP verwenden und 'implementiert' verwenden, um das Objekt- / Klassenskelett zu definieren
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)
}
}
// Sie können Schnittstellen mit anderen Schnittstellen erweitern
interface IMyObject {
label: string,
}
interface IMyObjectWithSize extends IMyObject{
size?: number
}
Zusätzlich zu den bereits bereitgestellten brillanten Antworten gibt es spürbare Unterschiede bei der Erweiterung von Typen gegenüber Schnittstellen. Ich bin kürzlich auf einige Fälle gestoßen, in denen eine Schnittstelle den Job nicht ausführen kann:
Die Dokumentation hat erklärt
- Ein Unterschied besteht darin, dass Schnittstellen einen neuen Namen erstellen, der überall verwendet wird. Typ-Aliase erstellen keinen neuen Namen. Beispielsweise verwenden Fehlermeldungen nicht den Aliasnamen. In älteren Versionen von TypeScript konnten Typ-Aliase nicht erweitert oder implementiert werden (und sie konnten auch keine anderen Typen erweitern / implementieren). Ab Version 2.7 können Typaliasnamen durch Erstellen eines neuen Schnittpunkttyps erweitert werden
- Wenn Sie jedoch mit einer Schnittstelle keine Form ausdrücken können und einen Union- oder Tupeltyp verwenden müssen, sind normalerweise Typaliasnamen der richtige Weg.