Interfaces TypeScript

Définition d’une interface

Une interface permet de décrire la forme d’un objet et de donner un nom à ce type.

Prenons un exemple :

function printName(obj: { name: string; age: number; }) {
  console.log(obj.name);
}

printName({name: 'Brad Pitt', age: 53});

Ici, on a utilisé le type { name: string; age: number; } pour imposer à l’argument obj de la fonction printName() d’être un objet avec une propriété name de type “string” et une propriété age de type “number”.

Comme nous avons déclaré le type “en ligne”, directement à côté de la variable sur laquelle il porte, notre code n’est pas très lisible. Une interface permettrait de nommer notre type et de déporter sa déclaration en début de fichier.

interface Person {
  name: string;
  age: number;
}

function printName(obj: Person) {
  console.log(obj.name);
}

printName({name: 'Brad Pitt', age: 53});

Ce nouveau code est équivalent au précédent, avec plusieurs avantages :

  • Le code est plus lisible et plus sémantique.
  • L’interface peut être utilisée plusieurs fois dans le code, via son nom Person. On pourrait même la déclarer dans son propre fichier en l’exportant (export interface Person { ... }), de sorte que n’importe quel fichier de notre application pourrait la réutiliser en l’important.

Syntaxe d’une interface

La syntaxe générale d’une interface est :

interface MyInterface {
  prop1: type;
  prop2: type;  // <-- Notez les points-virgules en fin de ligne
  prop3: type;
  ...
}
  • Utilisez la notation PascalCase pour le nom de l’interface.
  • Pensez à mettre un point-virgule à la fin de chaque ligne dans l’interface, et non pas une virgule comme dans un objet littéral.

Une interface peut être utilisée partout où un type peut être utilisé : pour typer une variable ou une propriété d’objet, pour typer un argument ou une valeur de retour de fonction, pour typer un paramètre de méthode, etc.

Propriétés facultatives dans une interface

Pour signaler qu’une (ou plusieurs) propriété(s) de l’interface est facultative, il suffit de placer un ? juste après son nom :

interface Person {
  name: string;
  age?: number;  // La propriété `age` est maintenant facultative
}

// Plus loin dans le code
printName({name: 'Brad Pitt'});  // On n'est plus obligé de passer la propriété `age`

Duck Typing

Le compilateur TypeScript présente une certaine tolérance lorsqu’il contrôle qu’une valeur est bien conforme à une interface.

Si la valeur est un objet littéral, elle doit être STRICTEMENT conforme à l’interface :

printName({name: 'Brad Pitt', age: 53);  // OK
printName({name: 'Brad Pitt', age: 53, job: 'actor'});  // ERREUR, car `job` n'existe pas dans l'interface `Person`

En revanche, si la valeur est une variable, elle doit posséder AU MOINS les propriétés définies dans l’interface mais elle peut en contenir d’autres :

const person1 = {name: 'Brad Pitt', age: 53};
printName(person1);  // OK, conforme à l'interface

const person2 = {name: 'Brad Pitt', age: 53, job: 'actor'};
printName(person2);  // OK, peut contenir des propriétés en plus

On appelle ce comportement le duck typing : si une variable ressemble fortement à ce qu’on attend, même si ce n’est pas exactement ce qu’on attend, elle est considérée comme valide.

Ce comportement est assez aligné avec la réalité du développement : si on passe un objet littéral, on le contrôle à 100% et on peut faire en sorte qu’il soit strictement conforme à l’interface. Si on passe une variable, elle peut avoir été initialisée ailleurs dans notre code (ou dans la base de données), et de ce fait il ne sera pas rare qu’elle contienne des propriétés en plus.

Informations

Tags : typescript

Dernière mise à jour :

Auteur : AngularChef

Qualité : Pas finalisé