Quelle est la différence entre ces déclarations (interface vs type)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Quelle est la différence entre ces déclarations (interface vs type)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Réponses:
Selon la spécification du langage TypeScript :
Contrairement à une déclaration d'interface, qui introduit toujours un type d'objet nommé, une déclaration d'alias de type peut introduire un nom pour tout type de type, y compris les types primitifs, d'union et d'intersection.
La spécification poursuit en mentionnant:
Les types d'interface présentent de nombreuses similitudes avec les alias de type pour les littéraux de type objet, mais comme les types d'interface offrent plus de fonctionnalités, ils sont généralement préférés aux types d'alias. Par exemple, le type d'interface
interface Point { x: number; y: number; }pourrait être écrit comme l'alias de type
type Point = { x: number; y: number; };Cependant, cela signifie que les capacités suivantes sont perdues:
Une interface peut être nommée dans une clause extend ou implements, mais un alias de type pour un littéral de type objet ne peutplus être vrai depuis TS 2.7.- Une interface peut avoir plusieurs déclarations fusionnées , mais pas un alias de type pour un littéral de type d'objet.
interface Point { x: number; } interface Point { y: number; }
extends or implementsn'est plus le cas. Le type peut être étendu et implémenté par a class. Voici un exemple typescriptlang.org/play/…
Les réponses actuelles et la documentation officielle sont obsolètes. Et pour ceux qui découvrent TypeScript, la terminologie utilisée n'est pas claire sans exemples. Vous trouverez ci-dessous une liste des différences à jour.
Les deux peuvent être utilisés pour décrire la forme d'un objet ou une signature de fonction. Mais la syntaxe diffère.
Interface
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
Alias de type
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
Contrairement à une interface, l'alias de type peut également être utilisé pour d'autres types tels que les primitives, les unions et les tuples.
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
Les deux peuvent être étendus, mais encore une fois, la syntaxe diffère. En outre, notez qu'une interface et un alias de type ne s'excluent pas mutuellement. Une interface peut étendre un alias de type et vice versa.
L'interface étend l'interface
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
L'alias de type étend l'alias de type
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
L'interface étend l'alias de type
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
L'alias de type étend l'interface
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
Une classe peut implémenter une interface ou un alias de type, les deux de la même manière exacte. Notez cependant qu'une classe et une interface sont considérées comme des plans statiques. Par conséquent, ils ne peuvent pas implémenter / étendre un alias de type qui nomme un type d'union.
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;
}
Contrairement à un alias de type, une interface peut être définie plusieurs fois et sera traitée comme une interface unique (les membres de toutes les déclarations étant fusionnés).
// 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 };
typeou interface? Je ne sais toujours pas quand je devrais utiliser l'un ou l'autre.
typede certaines limitations (et à partir de TypeScript 3.7, ces limitations ont également disparu). Les interfaces peuvent étendre les types. Les classes peuvent implémenter des types. De plus, la présentation des données sous forme de capture d'écran d'un tableau les rend complètement inaccessibles aux personnes malvoyantes.
https://www.typescriptlang.org/docs/handbook/advanced-types.html
Une différence est que les interfaces créent un nouveau nom qui est utilisé partout. Les alias de type ne créent pas de nouveau nom - par exemple, les messages d'erreur n'utilisent pas le nom d'alias.
// crée une arborescence pour un objet. Vous ne pouvez pas faire la même chose avec l'interface en raison du manque d'intersection (&)
type Tree<T> = T & { parent: Tree<T> };
// tapez pour restreindre une variable pour n'affecter que quelques valeurs. Les interfaces n'ont pas d'union (|)
type Choise = "A" | "B" | "C";
// grâce aux types, vous pouvez déclarer un type NonNullable grâce à un mécanisme conditionnel.
type NonNullable<T> = T extends null | undefined ? never : T;
// vous pouvez utiliser l'interface pour la POO et utiliser des 'implements' pour définir le squelette objet / classe
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)
}
}
// vous pouvez étendre les interfaces avec d'autres interfaces
interface IMyObject {
label: string,
}
interface IMyObjectWithSize extends IMyObject{
size?: number
}
En plus des réponses brillantes déjà fournies, il existe des différences notables en ce qui concerne l' extension des types par rapport aux interfaces. J'ai récemment rencontré quelques cas où une interface ne peut pas faire le travail:
la documentation a expliqué
- Une différence est que les interfaces créent un nouveau nom qui est utilisé partout. Les alias de type ne créent pas de nouveau nom - par exemple, les messages d'erreur n'utilisent pas le nom d'alias. Dans les anciennes versions de TypeScript, les alias de type ne pouvaient pas être étendus ou implémentés à partir (ni étendre / implémenter d'autres types). Depuis la version 2.7, les alias de type peuvent être étendus en créant un nouveau type d'intersection
- D'un autre côté, si vous ne pouvez pas exprimer une forme avec une interface et que vous devez utiliser un type union ou tuple, les alias de type sont généralement la solution.