TypeScript : types de base
Types primitifs
Section intitulée « Types primitifs »const nom: string = 'Alice';const age: number = 30;const actif: boolean = true;const rien: null = null;const absent: undefined = undefined;const grand: bigint = 9007199254740993n;const symbole: symbol = Symbol('id');Le plus souvent, ne pas annoter : l’inférence déduit le type.
const nom = 'Alice'; // type : "Alice" (littéral, car const)let compteur = 0; // type : numberconst liste = [1, 2, 3]; // type : number[]Annoter les paramètres et valeurs de retour des fonctions exportées (documentation et contrat), laisser l’inférence pour les variables locales.
Tableaux et tuples
Section intitulée « Tableaux et tuples »const noms: string[] = ['Alice', 'Bob'];const nombres: Array<number> = [1, 2, 3];const lectureSeule: readonly string[] = ['a', 'b']; // non modifiable
const paire: [string, number] = ['Alice', 30]; // tuple : longueur et types fixésconst [prenom, ageDeAlice] = paire;const nomme: [x: number, y: number] = [10, 20];Avec noUncheckedIndexedAccess, noms[0] vaut string | undefined : tester avant d’utiliser.
Unions et littéraux
Section intitulée « Unions et littéraux »type Identifiant = string | number;type Statut = 'nouvelle' | 'payee' | 'expediee'; // valeurs autorisées
function afficher(id: Identifiant) { return typeof id === 'string' ? id.toUpperCase() : id.toFixed(0);}
let statut: Statut = 'payee';statut = 'perdue'; // erreur : non autoriséLes unions de littéraux remplacent souvent les enum : plus simples, sans code généré.
enum et alternatives
Section intitulée « enum et alternatives »enum Couleur { Rouge, Vert, Bleu,} // génère du code JavaScriptconst COULEURS = ['rouge', 'vert', 'bleu'] as const;type CouleurLitterale = (typeof COULEURS)[number]; // 'rouge' | 'vert' | 'bleu'Préférer l’objet as const ou l’union de littéraux : pas de code propre à TypeScript (important pour l’exécution directe par Node.js, voir Installation).
const Role = { Admin: 'admin', Editeur: 'editeur' } as const;type Role = (typeof Role)[keyof typeof Role]; // 'admin' | 'editeur'any, unknown, never
Section intitulée « any, unknown, never »| Type | Sens | Usage |
|---|---|---|
any |
Désactive la vérification | À éviter : propage l’absence de contrôle |
unknown |
Valeur inconnue : on doit la vérifier avant de l’utiliser | Données externes, catch |
never |
Valeur qui n’existe pas | Fonction qui ne retourne jamais, vérification d’exhaustivité |
void |
Pas de valeur de retour | Fonctions sans return |
function analyser(entree: unknown): string { if (typeof entree === 'string') return entree; if (typeof entree === 'number') return String(entree); throw new TypeError('type non pris en charge');}
try { analyser({});} catch (erreur: unknown) { if (erreur instanceof Error) console.error(erreur.message);}unknown est la bonne réponse à « je ne connais pas le type » : on affine avant usage, contrairement à any.
Affinage (narrowing)
Section intitulée « Affinage (narrowing) »TypeScript restreint un type selon le code :
function longueur(valeur: string | string[] | null): number { if (valeur === null) return 0; // null éliminé if (typeof valeur === 'string') return valeur.length; return valeur.length; // ici : string[]}| Technique | Exemple |
|---|---|
typeof |
typeof x === 'string' |
instanceof |
erreur instanceof Error |
| Comparaison | x === null, x !== undefined |
| Propriété discriminante | if (forme.type === 'cercle') |
in |
'rayon' in forme |
| Fonction de garde | function estClient(x: unknown): x is Client { … } |
| Vérité | if (valeur) { … } (attention à 0 et '') |
Unions discriminées
Section intitulée « Unions discriminées »type Forme = | { type: 'cercle'; rayon: number } | { type: 'rectangle'; largeur: number; hauteur: number };
function aire(forme: Forme): number { switch (forme.type) { case 'cercle': return Math.PI * forme.rayon ** 2; case 'rectangle': return forme.largeur * forme.hauteur; default: { const inattendu: never = forme; // erreur si un cas n'est pas traité throw new Error(`forme inconnue : ${JSON.stringify(inattendu)}`); } }}La vérification avec never signale à la compilation un cas oublié quand on ajoute une variante à l’union.
Fonction de garde
Section intitulée « Fonction de garde »interface Client { id: number; nom: string;}
function estClient(valeur: unknown): valeur is Client { return ( typeof valeur === 'object' && valeur !== null && typeof (valeur as Client).id === 'number' && typeof (valeur as Client).nom === 'string' );}
const donnees: unknown = JSON.parse('{"id":1,"nom":"Alice"}');if (estClient(donnees)) console.log(donnees.nom);Pour des structures complexes, une bibliothèque de schémas (Zod) est plus sûre qu’une garde écrite à la main.
Valeurs absentes : null et undefined
Section intitulée « Valeurs absentes : null et undefined »Avec strict (donc strictNullChecks), null et undefined ne sont pas des valeurs de tout type :
function trouver(id: number): Client | undefined { /* ... */ return undefined;}
const client = trouver(1);console.log(client.nom); // erreur : « client » est peut-être « undefined »console.log(client?.nom); // chaînage optionnelconsole.log(client?.nom ?? 'inconnu'); // valeur par défautif (client) console.log(client.nom); // affinageL’opérateur ! (client!.nom) affirme que la valeur existe sans le vérifier : l’éviter, il masque de vraies erreurs.
Assertions de type
Section intitulée « Assertions de type »const entree = document.getElementById('nom') as HTMLInputElement; // assertionconst donnees = JSON.parse(texte) as Client; // aucune vérification réelle !Une assertion dit au compilateur « fais-moi confiance » : elle ne vérifie rien et peut mentir. À réserver aux cas où on sait mieux que le compilateur ; préférer l’affinage, une garde ou un schéma de validation.
L’opérateur satisfies vérifie la conformité sans élargir le type :
const couleurs = { rouge: [255, 0, 0], vert: '#00ff00',} satisfies Record<string, string | number[]>;
couleurs.rouge.map((n) => n / 2); // reste number[] (et non string | number[])as const
Section intitulée « as const »const config = { port: 3000, hotes: ['a', 'b'] } as const;// type : { readonly port: 3000; readonly hotes: readonly ['a', 'b'] }Fige la valeur et ses littéraux : utile pour des constantes dont on dérive un type.
Fonctions : types de base
Section intitulée « Fonctions : types de base »function additionner(a: number, b: number = 0): number { return a + b;}const double = (n: number): number => n * 2;function saluer(nom: string, ...titres: string[]): string { return `${titres.join(' ')} ${nom}`;}function journaliser(message: string): void { console.log(message);}const rappel: (valeur: number) => void = (n) => console.log(n);Voir Objets, interfaces et fonctions pour la suite.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
Type 'string | undefined' is not assignable to type 'string' |
Valeur facultative : valeur par défaut (??) ou test |
Object is possibly 'null' / 'undefined' |
Affiner (if, ?.), éviter ! |
Element implicitly has an 'any' type |
Indexation par une clé non typée : typer la clé (keyof) ou un Record |
Type 'string' is not assignable to type '"a" | "b"' |
Littéral élargi : as const ou annotation du type union |
Property 'x' does not exist on type 'never' |
Affinage qui a tout éliminé (union épuisée) |
Parameter 'x' implicitly has an 'any' type |
Annoter le paramètre (règle noImplicitAny de strict) |
JSON.parse renvoie any |
Valider avec un schéma plutôt que d’affirmer avec as |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Aucune.