frontend / typescript
Types de base
Explication
Ce que vous allez apprendre
- Déclarer une variable avec un type primitif explicite (
string,number,boolean...) - Distinguer
any(dangereux) deunknown(sûr) et savoir quand utiliser lequel - Créer et utiliser un tuple pour représenter une structure de taille fixe
- Différencier
void(rien à retourner) denever(ne se termine jamais normalement) - Repérer un
anyimplicite qui désactive silencieusement la vérification de type
Dans quel contexte ?
Un développeur reçoit une donnée JSON depuis une API externe et la stocke dans une variable typée any par facilité : const reponse: any = await res.json();. Trois mois plus tard, une modification de l'API renomme un champ email en emailAddress, et l'application plante en production avec Cannot read properties of undefined, sans que TypeScript n'ait jamais signalé le moindre problème à la compilation. Typer cette variable en unknown puis valider sa structure (avec une bibliothèque comme Zod, ou une vérification manuelle) aurait forcé le développeur à gérer explicitement ce champ avant de l'utiliser.
Donner un type à chaque valeur
En JavaScript, une variable peut changer de nature à tout moment : un nombre peut devenir une chaîne sans prévenir. TypeScript vous demande de déclarer, dès le départ, ce qu'une variable est censée contenir — un nombre, un texte, un booléen — puis fait respecter cette promesse tout au long du programme.
Prérequis
Cette leçon suppose la configuration de base de TypeScript (leçon 1) déjà en place, notamment strict: true, qui rend plusieurs des vérifications décrites ici réellement effectives.
Deux types fourre-tout à bien distinguer
any désactive complètement la vérification de type : c'est une porte de sortie pratique mais dangereuse, car TypeScript laisse alors écrire n'importe quelle instruction sur cette valeur, même absurde, et l'erreur n'apparaît qu'au runtime. unknown est son cousin prudent : il accepte n'importe quelle valeur au départ (typiquement une donnée venue de l'extérieur, comme une réponse JSON), mais interdit de l'utiliser tant qu'on n'a pas vérifié sa nature réelle avec un test comme typeof. Préférez toujours unknown à any quand la donnée vient d'une source non contrôlée.
| Type | Vérification à l'usage | Cas d'usage typique |
|---|---|---|
any | Aucune (dangereux) | À éviter, sauf migration progressive d'un projet JS |
unknown | Obligatoire avant usage | Donnée externe (API, JSON, fichier) |
Type précis (string, interface...) | Automatique | Toute donnée dont la structure est connue |
Piège fréquent
let danger: any = 42; danger.toUpperCase(); compile sans erreur mais plante au runtime (42.toUpperCase is not a function). any supprime toute protection : préférez systématiquement unknown associé à une vérification (typeof, instanceof) pour une donnée dont la forme n'est pas garantie.
Les tuples, un cas particulier des tableaux
Un tableau classique peut contenir un nombre variable d'éléments du même type. Un tuple, lui, fixe à l'avance combien d'éléments il contient ET le type de chacun selon sa position — pratique pour représenter des coordonnées ou une paire clé/valeur.
Void et never
void signifie que cette fonction ne renvoie rien d'utile (comme un console.log), tandis que never signifie que cette fonction ne se termine jamais normalement (elle lève systématiquement une exception ou boucle indéfiniment). Cette distinction paraît subtile aujourd'hui ; elle deviendra un outil puissant dans la leçon sur le narrowing avancé.
Commandes & code
Types de base
// Primitives
let nom: string = "Ada";
let age: number = 36;
let actif: boolean = true;
let vide: null = null;
let indefini: undefined = undefined;
let grandNombre: bigint = 123n;
let cle: symbol = Symbol("id");
// Tableaux
let notes: number[] = [12, 15, 18];
let mots: Array<string> = ["a", "b"];
// Tuples : longueur ET types fixés par position
let coord: [number, number] = [48.85, 2.35];
let entree: [string, number, boolean?] = ["clic", 1]; // 3e élément optionnel
let etiquettes: [nom: string, valeur: number] = ["taille", 42]; // tuple nommé, plus lisible
// any : désactive tout contrôle (à éviter)
let danger: any = 42;
danger.toUpperCase(); // compile, plante au runtime : 42.toUpperCase is not a function
// unknown : safe. Il FAUT vérifier le type avant usage
let valeurExterne: unknown = JSON.parse("{}");
if (typeof valeurExterne === "string") {
valeurExterne.toUpperCase(); // OK, narrowed en string
}
// valeurExterne.toUpperCase(); // Error si non vérifié avant
// void : fonction qui ne retourne rien d'utile
function log(msg: string): void {
console.log(msg);
}
// never : ne retourne JAMAIS (throw, boucle infinie, exhaustivité)
function fail(msg: string): never {
throw new Error(msg);
}
// object : n'importe quelle valeur non-primitive
let config: object = { a: 1 };| Type | Exemple | Usage |
|---|---|---|
any | let x: any | désactive tout contrôle, à éviter |
unknown | let x: unknown | safe, narrowing obligatoire avant usage |
never | function f(): never | ne retourne jamais (throw / boucle infinie) |
void | function f(): void | pas de valeur de retour utile |
Résumé
- Préférer
unknownàanydès que la source est externe (API, JSON, input). - Les tuples fixent longueur ET types par position ; utiles pour des retours multiples.
neversert aussi de garde-fou d'exhaustivité (voir la leçon sur le narrowing).
Exercices pratiques
Mission : traquer un any qui a fait planter la prod
Objectif : Diagnostiquer un bug provoqué par un any non vérifié, puis migrer le code vers unknown et un tuple sûr.
Contexte
Un développeur a écrit const reponse: any = await res.json(); pour lire la réponse d'une API externe. Trois mois plus tard, l'API renomme email en emailAddress, et le code plante en production avec Cannot read properties of undefined, sans qu'aucune erreur de compilation n'ait jamais signalé le problème. Ta mission : comprendre pourquoi any a laissé passer ce bug, puis sécuriser le code.