Interfaces TypeScript, de la syntaxe à interface vs type
Interfaces TypeScript
Interface TypeScript : syntaxe, extends, fusion, vs type | We.Inc
Construisez une interface champ par champ, voyez l'alias de type équivalent, et découvrez les membres optionnels et readonly, extends, la fusion de déclarations et les cas où un alias de type convient mieux.
Une interface nomme la forme d'un objet : quelles propriétés il possède et quel type contient chacune. Rendez une propriété optionnelle avec ? et non modifiable avec readonly, appuyez-vous sur une autre forme avec extends, et redéclarez le même nom pour y fusionner d'autres membres. Les interfaces ne laissent aucune trace dans le JavaScript compilé, elles guident uniquement le vérificateur de types.
La syntaxe des interfaces en un coup d'œil
Vous voulez
Écrivez
Une propriété obligatoire
name: string;
Une propriété optionnelle
nickname?: string;
Une propriété qui ne peut pas être réassignée
readonly id: number;
Une méthode
greet(other: User): string;
Un nombre quelconque de clés string
[key: string]: number;
Réutiliser une autre forme
interface Admin extends User { ... }
Combiner plusieurs formes
interface A extends B, C { ... }
Ajoutez des champs dans le générateur ci-dessous, cochez optionnel ou readonly, et copiez l'interface ou l'alias de type équivalent. Les sections suivantes couvrent l'extension, la fusion et les quelques cas où le choix entre interface et type compte vraiment.
Nommez l'interface et, si elle s'appuie sur une autre, saisissez ce nom dans le champ extends.
Ajoutez une ligne par propriété, en choisissant son type et si elle est optionnelle ou readonly.
Lisez l'interface et l'alias de type que le générateur écrit à partir des mêmes lignes.
Copiez l'une ou l'autre version dans votre code.
Commencez par interface pour les formes d'objets et passez à type quand vous avez besoin d'une union, d'un tuple ou d'un mapped type. C'est l'heuristique que suggère le handbook TypeScript lui-même.
readonly empêche seulement la réassignation de cette propriété précise. Les objets imbriqués à l'intérieur peuvent toujours changer, et rien n'est vérifié à l'exécution.
Une propriété optionnelle se lit comme son type ou undefined, vérifiez-la donc avant usage ou donnez-lui une valeur par défaut lors de la déstructuration.
Gardez des noms d'interface au singulier et descriptifs, comme Invoice ou CartItem. Un préfixe comme IInvoice n'apporte rien que l'éditeur ne vous dise déjà.
Questions fréquentes
Dois-je utiliser interface ou type ?
Pour les formes d'objets, les deux fonctionnent et le handbook parle surtout de préférence personnelle, en suggérant interface tant que vous n'avez pas besoin d'une fonctionnalité propre à type. Utilisez type pour les unions, les tuples, les primitives et les mapped ou conditional types, et interface quand vous voulez la fusion de déclarations.
Qu'est-ce que la fusion de déclarations ?
Déclarer une interface avec un nom qui existe déjà lui ajoute des membres au lieu d'échouer. Les bibliothèques s'appuient dessus pour vous permettre d'étendre leurs types, par exemple en ajoutant une propriété à Window. Un alias de type avec un nom répété provoque une erreur.
Que se passe-t-il si deux interfaces fusionnées donnent des types différents à une propriété ?
Le compilateur signale une erreur. Avec une intersection de deux types, le conflit n'est pas signalé à la déclaration : la propriété devient never, ce qui ne se manifeste que plus tard et est plus difficile à retrouver.
Une interface peut-elle décrire une fonction ou un tableau ?
Oui. Une signature d'appel comme (value: string): boolean décrit une fonction, et une index signature comme [index: number]: string décrit un objet de type tableau. Pour les cas simples, un alias de type comme type Check = (v: string) => boolean se lit plus clairement.
Les interfaces existent-elles à l'exécution ?
Non. Elles ne produisent aucun code compilé, vous ne pouvez donc pas utiliser instanceof avec une interface ni lister ses clés. Vérifiez les valeurs avec un garde à l'exécution et annotez son type de retour avec l'interface.
extends ou intersections
interface Bear extends Animal reprend chaque membre d'Animal et vous permet d'en ajouter d'autres. Un alias de type fait la même chose avec une intersection, type Bear = Animal & { honey: boolean }.
Le handbook note que extends peut être plus rapide pour le compilateur et qu'il signale les membres en conflit à l'endroit même où ils sont déclarés. Les intersections sont pratiques pour assembler des formes qui ne vous appartiennent pas.
Optionnel, readonly et index signatures
Un point d'interrogation après le nom rend une propriété optionnelle, et son type en lecture inclut undefined. readonly bloque l'assignation de cette propriété après sa création, mais il s'agit uniquement d'une vérification à la compilation.
Une index signature, [key: string]: number, décrit des dictionnaires dont vous ne pouvez pas lister les clés à l'avance. Les propriétés nommées de la même interface doivent être compatibles avec le type de valeur de l'index signature.
Fusionner pour étendre les types globaux et ceux des bibliothèques
Comme les interfaces fusionnent, un fichier de déclaration peut ajouter vos propres champs aux formes intégrées. Un cas courant consiste à donner à Window une propriété définie par un script, pour que sa lecture passe la vérification de types sans cast.
interface ou alias de type
Ce que chaque déclaration permet de faire
Fonctionnalité
alias de type
Décrire une forme d'objet
Oui
Oui
Ajouter des membres en redéclarant le nom
Oui (fusion)
Non, erreur d'identifiant dupliqué
S'appuyer sur une autre forme
Intersection avec &
Union de formes ou de littéraux
Non
Oui
Nommer une primitive ou un tuple
Non
Oui
Mapped et conditional types
Non
Oui
Les patterns que vous écrirez souvent
Étendre une ou plusieurs interfaces
Admin reçoit chaque membre de User plus les siens, Card combine deux formes sans rapport.
Fusion de déclarations sur Window
Placé dans un fichier .d.ts, ce code permet à window.appVersion de passer la vérification de types partout.
Index signature et signature d'appel
Scores accepte n'importe quelle clé string, Validator décrit une valeur appelable.
Générateur d'interface
Nom de l'interface
Extends (facultatif)
Nom de la propriété {n}
Type de la propriété {n}
Optionnelle
Readonly
Supprimer la propriété {n}
Ajouter une propriété
Sous forme d'interface
Sous forme d'alias de type
Copier l'interface
Copier le type
Les noms doivent commencer par une lettre, $ ou _ et ne contenir que des lettres, des chiffres, $ ou _.