Types littéraux TypeScript
Les types littéraux sont une fonctionnalité de TypeScript qui représente des valeurs spécifiques plutôt que des types génériques.
Il permet de restreindre le type de variable à des valeurs spécifiques, plutôt qu'à des types larges comme string, number, etc.
Cela offre un contrôle de type plus précis et rend le code plus sûr en termes de types.
Diagramme SVG : Types littéraux
Pourquoi les types littéraux sont nécessaires
En TypeScript, les types par défaut comme string et number sont trop larges.
Parfois, nous avons besoin d'un contrôle de type plus précis. Par exemple, une variable ne peut prendre que quelques valeurs spécifiques.
Les types littéraux sont précisément conçus pour résoudre ce genre de problèmes.
Explication du concept :Les types littéraux sont des valeurs concrètes de types généraux (string, number). Par exemple
"up"OuistringUn sous-type, et les seules valeurs qui peuvent lui être assignées sont des chaînes spécifiques.
Types littéraux de chaîne
Les types littéraux de chaîne limitent la variable à des valeurs de chaîne spécifiques.
Ceci est utile lorsque vous devez restreindre une variable pour qu'elle ne prenne que certaines valeurs fixes.
Exemple
// direction ne peut être que l'une des quatre valeurs spécifiques
var direction: "up" | "down" | "left" | "right";
// Correct : affecter une valeur issue du type littéral
direction = "up";
// Erreur : affecter une valeur absente de la liste
// direction = "upup"; // Erreur de compilation !
console.log("Direction : " + direction);
// Utilisez un alias de type pour créer un type littéral réutilisable
// Définissez un type de statut : il ne peut être que l'une des trois valeurs fixes
type Status = "pending" | "active" | "completed";
// Utilisez l'alias de type
var currentStatus: Status = "active";
console.log("Statut : " + currentStatus);
Sortie :
方向: up Status: active
Scénarios d'application :Les littéraux de chaîne sont souvent utilisés pour définir des valeurs d'énumération, des codes d'état, des options de configuration et d'autres scénarios qui doivent être restreints à des valeurs spécifiques.
Types littéraux numériques
Les types littéraux numériques restreignent la variable à des valeurs numériques spécifiques.
Cela est utile lorsque vous devez utiliser des valeurs numériques spécifiques (telles que des codes d'état, des codes d'erreur).
Exemple
// code ne peut être qu'une des trois valeurs spécifiques
var code: 200 | 404 | 500;
// Correct : affecter 200
code = 200;
// Erreur : affecter une valeur absente de la liste
// code = 301; // Erreur de compilation !
console.log("Code d'état : " + code);
// Utiliser des littéraux numériques pour simuler une énumération
// Définir les jours de la semaine
type Weekday = 1 | 2 | 3 | 4 | 5 | 6 | 7;
// On ne peut assigner que des nombres entre 1 et 7
var today: Weekday = 1;
console.log("Aujourd'hui, c'est le jour de la semaine : " + today);
Explication :Les littéraux numériques peuvent être utilisés en remplacement d'énumérations simples, surtout lorsque seules quelques valeurs numériques fixes sont nécessaires.
Types littéraux booléens
Les types littéraux booléens limitent la variable à true ou false.
En fait, le type boolean dans TypeScript est un alias de `true | false`.
Exemple
// isActive ne peut être que true ou false
var isActive: true | false;
// Affecter true
isActive = true;
// En fait, boolean est un type union de true | false
// Donc ces deux façons d'écrire sont équivalentes
var flag: boolean = true;
console.log("Is active: " + isActive);
Remarque :Bien que boolean soit suffisant en soi, lorsque vous avez besoin de distinguer clairement entre les types true et false, vous pouvez utiliser true ou false comme type.
Types littéraux d'objet
Les types littéraux d'objet peuvent définir la structure d'un objet, et peuvent utiliser le modificateur readonly pour rendre les propriétés en lecture seule.
C'est très utile lorsque vous avez besoin de créer des objets immuables.
Exemple
// Spécifier la structure de l'objet et les types de propriétés
type Point = {
// La coordonnée x du point
x: nombre;
// La coordonnée y du point
y: nombre;
};
// Utiliser le type littéral d'objet
var p: Point = { x: 10, y: 20 };
console.log("Point : " + JSON.stringify(p));
// Définir un type d'objet en lecture seule
// Utiliser le modificateur readonly pour rendre les propriétés en lecture seule
type ReadonlyPoint = {
// Coordonnée x en lecture seule
readonly x: number;
// Coordonnée y en lecture seule
readonly y: number;
};
// Utiliser le type d'objet en lecture seule
var rp: ReadonlyPoint = { x: 1, y: 2 };
// Tenter de modifier une propriété en lecture seule provoquera une erreur
// rp.x = 3; // Erreur de compilation : une propriété en lecture seule ne peut pas être modifiée
console.log("Point en lecture seule : " + JSON.stringify(rp));
Sortie :
点: {"x":10,"y":20}
只读点: {"x":1,"y":2}
Scénarios d'application :Les objets en lecture seule sont souvent utilisés pour définir des objets de configuration, des objets constants et d'autres données qui ne doivent pas être modifiés.
Types littéraux et inférence de types
TypeScript déduit automatiquement les types littéraux en fonction de la façon dont les variables sont déclarées.
Les variables déclarées avec const sont inférées comme des types littéraux spécifiques, plutôt que comme des types larges.
Exemple
// TypeScript inférera un type large
var name = "Alice"; // Type : string (car var peut être réaffecté)
var age = 25; // Type : number
var enabled = true; // Type : booléen
console.log("Nom : " + name + ", Âge : " + age + ", Activé : " + enabled);
// Utiliser as const pour créer un littéral profond en lecture seule
// Le tableau devient un tuple en lecture seule, et les valeurs sont des types littéraux
var colors = ["red", "green", "blue"] as const;
// Le type de colors devient :
// readonly ["red", "green", "blue"]
// Accéder aux éléments du tableau
console.log("Couleurs : " + colors[0]);
// Toute tentative de modification provoquera une erreur
// colors
Explication :
as constIl déduira le type comme le type littéral le plus spécifique et ajoutera le modificateur readonly.
Types littéraux de modèle
Les types littéraux de modèle utilisent la syntaxe des chaînes de modèle JavaScript pour créer de nouveaux types.
Cela nous permet de générer dynamiquement des types de chaînes.
Exemple
// `on${string}` représente toute chaîne commençant par "on"
type EventName = `on${string}`;
// Utiliser les types littéraux de modèle pour définir des noms de gestionnaires
// Capitalize convertit la première lettre d'une chaîne en majuscule
type Handler = `handle${Capitalize<string>}`;
// Utiliser le type littéral de modèle
var event: EventName = "onClick";
var handler: Handler = "handleSubmit";
console.log("Event: " + event);
console.log("Handler: " + handler);
// Erreur : ne correspond pas au format du modèle
// var e: EventName = "click"; // Erreur de compilation : ne commence pas par "on"
Résultat de l'exécution :
事件: onClick 处理器: handleSubmit
Types utilitaires intégrés :Les types littéraux de modèle peuvent être utilisés avec des types utilitaires intégrés tels que Uppercase, Lowercase, Capitalize, Uncapitalize, etc.
Application concrète : Redux Action
Les types littéraux ont un large éventail d'applications dans le développement réel.
Ce qui suit montre comment utiliser les types littéraux pour implémenter des actions de style Redux.
Exemple
// Utiliser les types union pour définir différents types d'actions
type Action =
// Action de type increment, contenant un payload numérique
| { type: "increment"; payload: number }
// Action de type decrement, contenant un payload numérique
| { type: "decrement"; payload: number }
// Action de type reset, sans payload
| { type: "reset" };
// Fonction reducer qui utilise action
function reducer(action: Action): void {
// TypeScript déduira automatiquement le type spécifique de l'action en fonction de la valeur de action.type
switch (action.type) {
case "increment":
// Dans cette branche, action est inférée comme { type: "increment"; payload: number }
console.log("Incrément : " + action.payload);
break;
case "decrement":
// Dans cette branche, action est inférée comme { type: "decrement"; payload: number }
console.log("Decrement: " + action.payload);
break;
case "reset":
// Dans cette branche, action est inférée comme { type: "reset" }
console.log("Reset");
break;
}
}
// Dispatcher différents types d'actions
reducer({ type: "increment", payload: 5 });
reducer({ type: "reset" });
Résultat de l'exécution :
增加: 5 重置
Union discriminée :Ce modèle est appelé une « union discriminée », qui est la meilleure pratique pour gérer plusieurs types liés en TypeScript.
Notes
- Rétrécissement de type :Lors de l'utilisation de switch ou de vérifications if, TypeScript réduit automatiquement les types littéraux
- Alias de type :Il est recommandé d'utiliser des alias de type pour créer des alias pour les types littéraux couramment utilisés
- Inférence const :Les variables déclarées avec const sont automatiquement inférées comme des types littéraux
- as const:Utilisez as const lorsqu’un readonly profond est nécessaire
Bonnes pratiques :Lorsque vous devez restreindre une variable à des valeurs spécifiques, préférez les types littéraux aux enums.
Résumé
Les types littéraux sont une fonctionnalité importante de TypeScript pour obtenir un contrôle précis des types.
- Littéraux de chaîne :Restreints à des chaînes spécifiques, telles que
"up" | "down" - Littéraux numériques :Restreints à des nombres spécifiques, tels que
1 | 2 | 3 - Littéraux booléens :Restreints à true ou false
- Littéraux d’objet :Définissent la structure d’un objet, peuvent utiliser readonly
- as const:Créez des types littéraux readonly profonds
- Littéraux de modèle :Générez dynamiquement des types à l’aide de chaînes de modèle
Autres extensionsAvancé :La combinaison des types littéraux avec le modèle d’union discriminée permet une puissante sécurité de type.