Protections de type TypeScript

Les protections de type sont une fonctionnalité puissante de TypeScript qui permet aux développeurs d'effectuer des vérifications d'exécution pour affiner le type d'une variable. Cela garantit des informations de type plus précises, ce qui conduit à un code plus sûr et plus prévisible. Cet article explique ce que sont les protections de type et comment les utiliser efficacement.

Que sont les protections de type ?

Les protections de type sont des expressions qui effectuent des vérifications à l'exécution et permettent à TypeScript de déduire un type plus spécifique pour une variable. Elles aident à distinguer différents types, en particulier lorsqu'il s'agit de types d'union. Les protections de type peuvent être implémentées à l'aide de diverses techniques, notamment:

  • Prédicats de type définis par l'utilisateur
  • Assertions de type
  • Vérifications d'instance
  • Utilisation de l'opérateur typeof
  • Utilisation de l'opérateur in

Prédicats de type définis par l'utilisateur

Les prédicats de type définis par l'utilisateur sont des fonctions qui renvoient une valeur booléenne et ont un type de retour spécial qui indique le type de la variable vérifiée. Voici comment les créer et les utiliser:

function isString(value: any): value is string {
  return typeof value === 'string';
}

function printString(value: any) {
  if (isString(value)) {
    console.log(value.toUpperCase()); // TypeScript knows value is a string here
  } else {
    console.log('Not a string');
  }
}

Dans l'exemple ci-dessus, isString est un prédicat de type défini par l'utilisateur qui aide TypeScript à comprendre que value est une chaîne dans le bloc if.

Assertions de type

Les assertions de type indiquent à TypeScript de traiter une variable comme un certain type. Cette méthode n'effectue pas de vérification à l'exécution mais informe le compilateur TypeScript du type. Par exemple:

function printLength(value: any) {
  console.log((value as string).length); // Assert value is a string
}

Dans cet exemple, value as string indique à TypeScript de supposer que value est une chaîne sans effectuer de vérification d'exécution.

Vérifications d'instance

Les vérifications d'instances permettent de déterminer si un objet est une instance d'une classe particulière. Cela est utile pour affiner les types lorsque vous travaillez avec des classes:

class Dog {
  bark() { console.log('Woof'); }
}

class Cat {
  meow() { console.log('Meow'); }
}

function speak(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark(); // TypeScript knows animal is a Dog here
  } else {
    animal.meow(); // TypeScript knows animal is a Cat here
  }
}

Dans cet exemple, l'opérateur instanceof aide TypeScript à déduire le type de animal en fonction de sa classe.

Utilisation de l'opérateur typeof

L'opérateur typeof peut être utilisé pour vérifier les types primitifs tels que string, number et boolean:

function processValue(value: string | number) {
  if (typeof value === 'string') {
    console.log(value.toUpperCase()); // TypeScript knows value is a string here
  } else {
    console.log(value.toFixed(2)); // TypeScript knows value is a number here
  }
}

Ici, typeof est utilisé pour vérifier si value est une string ou un number et restreint le type en conséquence.

Utilisation de l'opérateur in

L'opérateur in vérifie la présence d'une propriété dans un objet. Il est utile pour distinguer les types qui partagent des propriétés communes:

interface Bird {
  fly: () => void;
}

interface Fish {
  swim: () => void;
}

function move(creature: Bird | Fish) {
  if ('fly' in creature) {
    creature.fly(); // TypeScript knows creature is a Bird here
  } else {
    creature.swim(); // TypeScript knows creature is a Fish here
  }
}

Dans cet exemple, l'opérateur in aide TypeScript à déterminer si creature est un Bird ou un Fish en fonction de la présence d'une méthode.

Conclusion

Les protections de type TypeScript sont des outils essentiels pour travailler avec des types de manière flexible et sûre. Elles permettent une vérification de type plus précise et peuvent éviter les erreurs d'exécution en garantissant que le type correct est utilisé dans différents scénarios. La compréhension et l'utilisation efficaces des protections de type peuvent conduire à un code TypeScript plus robuste et plus facile à gérer.