Le deuxième tutoriel de notre série TypeScript for Beginners s'est concentré sur les types de données de base disponibles dans TypeScript. La vérification de type dans TypeScript nous permet de nous assurer que les variables de notre code ne peuvent avoir que des types spécifiques de valeurs attribuées. De cette façon, nous pouvons éviter beaucoup d'erreurs lors de l'écriture de code car l'EDI sera en mesure de nous dire quand nous effectuons une opération sur un type qu'il ne supporte pas. Cela fait de la vérification de type une des meilleures fonctionnalités de TypeScript.
Dans ce tutoriel, nous allons nous concentrer sur une autre caractéristique importante de ces génériques de langage. Avec les génériques, TypeScript vous permet d'écrire du code pouvant agir sur divers types de données au lieu d'être limité à un seul. Vous en apprendrez plus sur le besoin de génériques en détail et sur la façon dont il vaut mieux que de simplement utiliser le tout
type de données disponible dans TypeScript.
Si vous ne connaissez pas les génériques, vous vous demandez peut-être pourquoi nous en avons besoin. Dans cette section, je vais répondre à cette question pour vous. Commençons par écrire une fonction qui renverra un élément aléatoire à partir d'un tableau de nombres.
function randomIntElem (theArray: number []): number let randomIndex = Math.floor (Math.random () * theArray.length); renvoyer theArray [randomIndex]; let positions: nombre [] = [103, 458, 472, 458]; let randomPosition: number = randomIntElem (positions);
le randomElem
La fonction que nous venons de définir prend un tableau de nombres comme seul paramètre. Le type de retour de la fonction a également été spécifié sous forme de nombre. Nous utilisons le Math.random ()
fonction pour renvoyer un nombre aléatoire à virgule flottante compris entre 0 et 1. Le multiplier par la longueur d'un tableau donné et appeler Math.floor ()
sur le résultat nous donne un index aléatoire. Une fois que nous avons l'index aléatoire, nous retournons l'élément à cet index spécifique.
Quelque temps plus tard, supposons que vous deviez obtenir un élément de chaîne aléatoire à partir d'un tableau de chaînes. À ce stade, vous pouvez décider de créer une autre fonction qui cible spécifiquement les chaînes..
function randomStrElem (theArray: string []): string let randomIndex = Math.floor (Math.random () * theArray.length); renvoyer theArray [randomIndex]; let colors: string [] = ['violet', 'indigo', 'bleu', 'vert']; let randomColor: string = randomStrElem (couleurs);
Que faire si vous devez sélectionner un élément aléatoire dans un tableau d'une interface que vous avez définie? Il est impossible de créer une nouvelle fonction chaque fois que vous souhaitez obtenir un élément aléatoire à partir d'un tableau de types d'objets différents..
Une solution à ce problème consiste à définir le type de paramètre de tableau transmis aux fonctions en tant que tout[]
. De cette façon, vous ne pouvez écrire votre fonction qu’une seule fois et elle fonctionnera avec un tableau de tous les types..
function randomElem (theArray: any []): any let randomIndex = Math.floor (Math.random () * theArray.length); renvoyer theArray [randomIndex]; let positions = [103, 458, 472, 458]; let randomPosition = randomElem (positions); let couleurs = ['violet', 'indigo', 'bleu', 'vert']; let randomColor = randomElem (couleurs);
Comme vous pouvez le constater, nous pouvons utiliser la fonction ci-dessus pour obtenir des positions aléatoires ainsi que des couleurs aléatoires. Un problème majeur de cette solution est que vous perdrez les informations sur le type de valeur renvoyée..
Plus tôt, nous étions sûrs que randomPosition
serait un nombre et couleur aléatoire
serait une chaîne. Cela nous a aidés à utiliser ces valeurs en conséquence. Maintenant, tout ce que nous savons, c'est que l'élément retourné peut être de n'importe quel type. Dans le code ci-dessus, nous pourrions spécifier le type de couleur aléatoire
être un nombre
et toujours pas d'erreur.
// Ce code sera compilé sans erreur. let couleurs: string [] = ['violet', 'indigo', 'bleu', 'vert']; let randomColor: nombre = randomElem (couleurs);
Une solution plus efficace pour éviter la duplication de code tout en préservant les informations de type consiste à utiliser des génériques. Voici une fonction générique qui renvoie des éléments aléatoires d'un tableau.
fonction randomElem(theArray: T []): T let randomIndex = Math.floor (Math.random () * theArray.length); renvoyer theArray [randomIndex]; let colors: string [] = ['violet', 'indigo', 'bleu', 'vert']; let randomColor: chaîne = randomElem (couleurs);
Maintenant, je vais avoir une erreur si j'essaie de changer le type de couleur aléatoire
de chaîne
à nombre
. Cela prouve que l’utilisation de génériques est beaucoup plus sûre que l’utilisation du tout
tapez dans de telles situations.
La section précédente expliquait comment utiliser des génériques au lieu des tout
tapez afin d'écrire une seule fonction et évitez de sacrifier les avantages de la vérification de type. Un problème avec la fonction générique que nous avons écrite dans la section précédente est que TypeScript ne nous permet pas d’effectuer beaucoup d’opérations sur les variables.
En effet, TypeScript ne peut émettre aucune hypothèse sur le type de variable qui sera passé à notre fonction générique au préalable. En conséquence, notre fonction générique ne peut utiliser que les opérations applicables à tous les types de données. L'exemple suivant devrait clarifier ce concept.
function removeChar (theString: string, theChar: string): string let theRegex = new RegExp (theChar, "gi"); return theString.replace (theRegex, ");
La fonction ci-dessus supprimera toutes les occurrences du caractère spécifié de la chaîne donnée. Vous souhaiterez peut-être créer une version générique de cette fonction afin de pouvoir également supprimer des chiffres spécifiques d'un nombre donné ainsi que des caractères d'une chaîne. Voici la fonction générique correspondante.
fonction removeIt(theInput: T, theIt: string): T let theRegex = new RegExp (theIt, "gi"); renvoyer theInput.replace (theRegex, ");
le removeChar
la fonction ne vous a pas montré d'erreur. Cependant, si vous utilisez remplacer
à l'intérieur enlever
,TypeScript vous dira que remplacer
n'existe pas pour le type 'T'. En effet, TypeScript ne peut plus supposer que l'entrée
va être une chaîne.
Cette restriction sur l'utilisation de différentes méthodes dans une fonction générique peut vous amener à penser que le concept de générique ne sera pas d'une grande utilité après tout. Il n'y a pas grand-chose que vous puissiez faire avec une poignée de méthodes qui doivent être applicables à tous les types de données pour pouvoir les utiliser dans une fonction générique..
Une chose importante à retenir à ce stade est qu'il n'est généralement pas nécessaire de créer des fonctions qui seront utilisées avec toutes sortes de types de données. Il est plus courant de créer une fonction qui sera utilisée avec un ensemble ou une plage de types de données spécifique. Cette contrainte sur les types de données rend les fonctions génériques beaucoup plus utiles.
Le générique enlever
fonction de la section précédente a montré une erreur parce que le remplacer
méthode à l'intérieur de celui-ci est destiné à être utilisé avec des chaînes, tandis que les paramètres qui lui sont transmis pourraient avoir n'importe quel type de données.
Vous pouvez utiliser le s'étend
mot-clé pour contraindre les types de données transmis à une fonction générique dans TypeScript. toutefois, s'étend
est limité à seulement des interfaces et des classes. Cela signifie que la plupart des fonctions génériques que vous créez auront des paramètres qui étendront une interface ou une classe de base..
Voici une fonction générique qui affiche le nom des personnes, des membres de la famille ou des célébrités qui lui ont été transmis.
interface People nom: chaîne interface Famille nom: chaîne, âge: nombre, relation: chaîne interface Celebrity s´élargit Personnes profession: chaîne fonction nomProfil(theInput: T): void console.log ('Mon nom est $ theInput.name'); let serena: Celebrity = nom: 'Serena Williams', profession: 'joueuse de tennis' printName (serena);
Dans l’exemple ci-dessus, nous avons défini trois interfaces et chacune d’elles a une prénom
propriété. Le générique printName
fonction que nous avons créée acceptera n'importe quel objet qui s'étend Personnes
. En d'autres termes, vous pouvez transmettre à cette fonction un objet appartenant à la famille ou à une célébrité, qui affichera alors son nom sans aucune réclamation. Vous pouvez définir beaucoup plus d'interfaces, et tant qu'elles ont un prénom
propriété, vous pourrez utiliser le printName
fonctionner sans problème.
Cet exemple était très basique, mais vous pouvez créer des fonctions génériques plus utiles une fois que vous êtes plus à l'aise avec l'ensemble du processus. Par exemple, vous pouvez créer une fonction générique qui calcule la valeur totale des différents articles vendus au cours d’un mois donné, à condition que chaque article ait un prix
propriété pour stocker le prix et un vendu
propriété qui stocke le nombre d'articles vendus. En utilisant des génériques, vous pourrez utiliser la même fonction à condition que les éléments étendent la même interface ou la même classe..
Dans ce tutoriel, j'ai essayé de couvrir les bases des génériques dans TypeScript de manière conviviale pour les débutants. Nous avons commencé l'article en discutant du besoin de génériques. Nous avons ensuite appris comment utiliser les génériques de manière appropriée pour éviter la duplication de code sans sacrifier la capacité de vérification de type. Une fois que vous avez compris les bases abordées ici, vous pouvez en savoir plus sur les génériques dans la documentation officielle..
Si vous avez des questions concernant ce tutoriel, il me fera plaisir de répondre à vos commentaires..