TL;DR : TypeScript Generics permet aux développeurs d'écrire du code réutilisable qui peut fonctionner avec différents types de données tout en maintenant la sécurité des types. Ils sont essentiels pour créer des applications TypeScript robustes et évolutives.
Pour garantir que le code soit transparent et gérable, Typescript nécessite la gestion sûre et efficace de plusieurs types de données. L'une des fonctionnalités principales de Typescript est les génériques Typescript, qui permettent la création de fonctions, de classes et d'interfaces tout en respectant des limitations de type strictes. Les génériques vous permettent d'écrire moins de code, de faire moins d'erreurs et, surtout, de créer des composants flexibles pour différents types de données.
Cet article explore l'essentiel des génériques dactylographiés, y compris leur utilisation dans les fonctions, les classes et les interfaces, et montre comment ils rendent le code polyvalent et robuste.
Les génériques Typescript peuvent définir du code TypeScript avec des types d'espace réservé, ce qui lui permet d'être flexible, extensible et réutilisable tout en restant sécurisé.
Typescript effectue des contrôles de sécurité des types pendant la compilation en tant qu'espace réservé qui définit un type générique. Lorsque le composant est implémenté, le type réel remplace l'espace réservé. Cette technique facilite la gestion et la réduction de la duplicité car vous n'avez pas besoin d'implémentations distinctes pour chaque type de données.
Sans génériques, vous écririez plusieurs versions d'une fonction ou d'une classe pour gérer différents types de données, ce qui entraînerait une duplication de code. Les génériques permettent une implémentation unique réutilisable sur différents types tout en conservant la vérification de type statique.
Les exemples de code de la section suivante vous aideront à comprendre cette différence.
Les génériques peuvent être utilisés dans différentes parties du texte dactylographié pour aider à gérer les types plus efficacement. Ils jouent un rôle déterminant dans les fonctions, interfaces, classes et autres structures où la flexibilité est essentielle.
Les génériques sont souvent appliqués dans les fonctions pour réduire la redondance. Par exemple, considérons une fonction qui prend une chaîne ou un nombre comme paramètre.
function identity(value: any): any { return value; } const result1 = identity(42); // result1: any const result2 = identity("hello"); // result2: any
Cette fonction fonctionne bien. Mais il utilise n’importe quel type, ce qui signifie que Typescript perd la trace du type spécifique. Par conséquent, la valeur de retour est saisie comme any, et Typescript ne peut plus appliquer la sécurité des types. Si nous devons maintenir la sécurité des types, nous devrons écrire deux fonctions différentes, l’une renvoyant une chaîne tandis que l’autre renvoie un nombre. Cependant, cette approche augmentera la duplication de code.
Nous pouvons améliorer la fonction ci-dessus en utilisant des génériques pour préserver les informations de type.
function identity(value: any): any { return value; } const result1 = identity(42); // result1: any const result2 = identity("hello"); // result2: any
Le T représente le type que la méthode utilise dans ce cas. S'il est présent, Typescript confirmera que le type d'entrée et le type dans le paramètre de retour sont les mêmes.
De plus, nous pouvons définir la fonction sans définir explicitement le type de paramètre.
function identity<T>(value: Type): T { return value; } const result1 = identity<number>(42); // result1: number const result2 = identity<string>("hello"); // result2: string
Dans Typescript, vous pouvez utiliser plusieurs paramètres de type générique lorsque vous travaillez avec plusieurs types dans une seule fonction ou un seul composant. Par exemple, vous souhaiterez peut-être une fonction qui prend deux types d'entrées différents et les renvoie par paire.
const result3 = identity(100); // result3: number const result4 = identity("world"); // result4: string
Dans ce cas, la fonction renvoie un tuple avec un premier élément de type T et un deuxième élément de type U. Cela permet une gestion sécurisée de deux types distincts par la fonction.
Dans Typescript, vous pouvez fournir un type par défaut pour un générique, le rendant facultatif. Si aucun type n'est fourni, Typescript utilisera le type par défaut.
function multipleParams<T, U>(first: T, second: U): [T, U] { return [first, second]; } const result1 = multipleParams<string, number>("hello", 42); // result1: [string, number] const result2 = multipleParams<string, number>("hello", "world"); // result2: gives a type error
Dans cet exemple, le paramètre de type T est par défaut une chaîne. Si le développeur n'indique pas de type spécifique lorsqu'il appelle la fonction, T sera une chaîne par défaut.
Les génériques Typescript peuvent également être appliqués aux interfaces. Imaginez que vous souhaitiez définir une interface Box avec une valeur de n'importe quel type.
function createArray<T = string>(length: number, value: T): T[] { return Array(length).fill(value); } const stringArray = createArray(3, "hello"); // T defaults to string, so stringArray is a string array const numberArray = createArray<number>(3, 42); // T is explicitly set to a number, so numberArray is a number array
C'est plus égal à l'exemple des fonctions génériques ; ce code fonctionnera également sans problème puisque nous n'avons pas défini de type spécifique. Mais comme la valeur est saisie comme any, nous pouvons rencontrer des bugs liés au type.
Pour sécuriser le type, on peut définir ici une interface générique.
interface Box { value: any; } const numberBox: Box = { value: 123 }; // correct const stringBox: Box = { value: "hello" }; // correct
L'interface est générique, et son type de valeur est strictement contraint à la variable Type. La variable Type peut être spécifiée sous forme de nombre ou de chaîne lors de la création d'une instance afin que le Typescript garantisse que les types appropriés sont respectés.
Les classes peuvent également être écrites en utilisant des génériques pour gérer différents types tout en maintenant la sécurité des types. Créons une classe Storage qui peut stocker et récupérer des valeurs de n'importe quel type.
interface Box<Type> { value: Type; } const numberBox: Box<number> = { value: 123 }; // number const stringBox: Box<string> = { value: "hello" }; // string const stringBox2: Box<string> = { value: 123 }; // incorrect
Cette classe fonctionne, mais comme les données sont de type any, la méthode getItem renvoie any, supprimant la sécurité de type. Nous pouvons donc réécrire la classe en utilisant des génériques pour améliorer la sécurité des types.
class Storage { private data: any; setItem(item: any): void { this.data = item; } getItem(): any { return this.data; } } const storage = new Storage(); storage.setItem(123); const item = storage.getItem();
Dans ce cas, le type T est utilisé par la classe Storage. Typescript garantit que les données sont correctes lorsque vous définissez leur type lorsque vous créez une instance. La méthode getItem dans cet exemple de code donnera un nombre.
Vous pouvez utiliser des contraintes génériques pour restreindre les types qu'un générique peut accepter, en vous assurant qu'ils ont des propriétés spécifiques.
Par exemple, si vous avez une fonction qui doit accéder à la propriété length d'une entrée, vous pouvez utiliser une contrainte pour garantir que seuls les types avec une propriété length sont autorisés . Cela empêche Typescript de générer des erreurs ou de laisser passer des types incompatibles.
function identity(value: any): any { return value; } const result1 = identity(42); // result1: any const result2 = identity("hello"); // result2: any
Ici, la valeur T n'est pas définie avec la propriété length. Pour ignorer le problème, nous pouvons ajouter une contrainte spécifiant que T doit avoir une propriété length. Nous faisons cela en disant T extends { length: number }.
function identity<T>(value: Type): T { return value; } const result1 = identity<number>(42); // result1: number const result2 = identity<string>("hello"); // result2: string
Maintenant, cette fonction aura la propriété length ; il ne donnera aucune erreur et s'exécutera avec la longueur de l'entrée.
Les génériques Typescript vous permettent d'écrire du code flexible, recyclable et sécurisé. Vous pouvez gérer de nombreux types de données sans répéter le code à l'aide de classes, de méthodes et d'interfaces avec ces génériques. Les contraintes génériques, les nombreux types et les types par défaut sont quelques-uns des principaux cas d'utilisation que nous avons examinés dans cet article et avons montré comment chacun peut améliorer l'évolutivité et la maintenabilité des programmes.
Comprendre les génériques Typescript peut vous aider à écrire un code plus précis, adaptable et plus sûr, rendant vos applications Typescript plus robustes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!