Utilisation des paramètres de type dans les contraintes des génériques en TypeScript

TypeScript offre également la possibilité de déclarer un paramètre de type qui sera contraint par un autre paramètre de type. Cela est nécessaire lorsqu'il faut copier les propriétés d'un objet dans un autre, tout en se prémunir contre le fait de transmettre une propriété excédentaire.

Examinons l'exemple suivant. Revenons à la fonction myFunc, déterminant la longueur d'une variable :

typescriptfunction myFunc <T> (data: T): T {
  console.log(data.length); // erreur
  return data;
}

Cependant, nous voulons maintenant que cette fonction fonctionne uniquement avec les types ayant une propriété length. Pour ce faire, créons une interface ILength, à laquelle nous attribuerons une propriété length de type numérique :

typescriptinterface ILength {
  length: number;
}

Ensuite, dans notre fonction, définissons un type générique qui hérite de ILength via le mot-clé extends :

typescriptfunction myFunc <T extends ILength> (data: T): T {
  console.log(data.length);
  return data;
}

Voici à quoi ressemble notre code complet :

typescriptinterface ILength {
  length: number;
}

function myFunc <T extends ILength> (data: T): T {
  console.log(data.length);
  return data;
}

Vérifions le fonctionnement de notre fonction et trouvons la longueur d'une chaîne de caractères :

typescriptconsole.log(myFunc('abcde'));

Résultat de l'exécution du code :

typescript5
'abcde'

Et maintenant, passons un tableau en paramètre :

typescriptconsole.log(myFunc(['a', 'b', 'c']));

Résultat de l'exécution du code :

typescript3
[ 'a', 'b', 'c' ]