TypeScript J3

Tableaux · Tuples · Union Types · Narrowing

Typer le contenu de vos tableaux · Structurer des données complexes · Raisonner sur des types multiples

Objectifs de la leçon

1. Tableaux typés

Savoir écrire number[] et Array<number>

2. Tuples

Comprendre [string, number] et quand les utiliser

3. Union Types

Maîtriser string | number et string | null

4. Type Narrowing

Savoir restreindre un type avec typeof

Plan du cours

1. Recap J2

Types primitifs, annotations de fonctions, any vs unknown

2. Tableaux typés

number[] vs Array<number> — protéger le contenu

3. Tuples

[string, number] — taille fixe, types précis

4. Union Types

string | number — le OU des types

5. Type Narrowing avec typeof

TypeScript suit ta logique dans les if/else

Module 1

Recap J2

Types primitifs · annotations de fonctions · any vs unknown

Ce qu'on a vu en J2

Types primitifs

const nom: string = "Alice"

const age: number = 30

const actif: boolean = true

Annotations de fonctions

function saluer(

nom: string

): string {

return `Bonjour ${nom}!`

}

any vs unknown

✗ any — dangereux

let val: any = "texte"

val.toFixed() // pas d'erreur !

✓ unknown — sécurisé

let val: unknown = "texte"

if (typeof val === "number") {

val.toFixed() // OK

}

Aujourd'hui on monte d'un niveau : les structures de données

Module 2

Tableaux typés

number[] vs Array<number> — protéger le contenu

Typer un tableau

En TypeScript, on précise le type des éléments que le tableau peut contenir

Tableau de nombres

const scores: number[] = [10, 20, 30]

const ids: Array<number> = [1, 2, 3]

Tableau de chaînes

const noms: string[] = ["Alice", "Bob"]

const tags: Array<string> = ["ts", "js"]

// TypeScript bloque les erreurs de type

const notes: number[] = [15, 17]

notes.push("vingt") // âś— Erreur : string n'est pas number

Le typage protège le contenu : impossible d'ajouter le mauvais type !

number[] vs Array<number>

Deux syntaxes, exactement identiques pour TypeScript

✓ Syntaxe courte — préférée

number[]

string[]

boolean[]

Plus lisible, plus compact, convention TS

Syntaxe générique

Array<number>

Array<string>

Array<boolean>

Plus verbeux — même résultat compilé

Convention : dans le code professionnel, on utilise presque toujours number[] — plus court et tout aussi expressif

Ce que TypeScript vérifie sur les tableaux

Les opérations sur le tableau respectent le type déclaré

const scores: number[] = [10, 20, 30]

// ✓ Opérations valides

scores.push(40)

const total = scores.reduce((a, b) => a + b, 0)

const premier: number = scores[0] // TypeScript sait que c'est un number

// ✗ Opérations invalides

scores.push("bonus") // Erreur : string n'est pas number

const x: string = scores[0] // Erreur : number n'est pas string

push / pop

Éléments validés

Accès par index

Type inféré automatiquement

map / filter

Retour typé aussi

Module 3

Les Tuples

Taille fixe · Types précis · Idéal pour les retours multiples

Les tuples — qu'est-ce que c'est ?

Un tableau dont on connaît exactement la taille ET le type de chaque élément

Déclaration d'un tuple

const coordonnees: [number, number] = [48.8, 2.35]

const entree: [string, number] = ["Alice", 30]

const flag: [string, boolean] = ["actif", true]

Accès aux éléments

const user: [string, number] = ["Bob", 25]

const nom: string = user[0] // "Bob"

const age: number = user[1] // 25

// Destructuration

const [n, a] = user

TypeScript connaît le type de chaque position — user[0] est un string, user[1] est un number

Tuples : retours multiples de fonctions

Le cas d'usage le plus courant — retourner plusieurs valeurs de types différents

// Fonction qui retourne un tuple

function getUser(id: number): [string, number] {

return ["Alice", 30] // [nom, age]

}

// Utilisation avec destructuration

const [nom, age] = getUser(1)

console.log(`${nom} a ${age} ans`) // "Alice a 30 ans"

// Autre exemple : [succès, message]

function valider(email: string): [boolean, string] {

if (email.includes("@")) return [true, "OK"]

return [false, "Email invalide"]

}

const [ok, msg] = valider("alice@mail.com")

Piège : number[] vs [number, number]

La confusion la plus fréquente avec les tuples

Tableau variable number[]

const notes: number[] = [10, 20]

notes.push(30) // OK

notes.push(40) // OK

  • • Longueur variable
  • • Tous les Ă©lĂ©ments du mĂŞme type
  • • Pour les collections de donnĂ©es

Tuple fixe [number, number]

const point: [number, number] = [48, 2]

point.push(3) // Déconseillé !

  • • Longueur fixe (2 Ă©lĂ©ments)
  • • Chaque position a son propre type
  • • Pour les structures Ă  forme connue

Règle : number[] = liste de nombres · [number, number] = paire précise comme des coordonnées GPS

Module 4

Union Types

Le | des types — très courant avec null

Les Union Types — le OU des types

Une variable peut avoir l'un ou l'autre des types listés

Syntaxe de base

let valeur: string | number

valeur = "bonjour" // âś“

valeur = 42 // âś“

valeur = true // âś— Erreur

En paramètre de fonction

function afficher(

val: string | number

): void {

console.log(val)

}

afficher("hello") // âś“

afficher(99) // âś“

Le | se lit "ou" : string | number = "une chaîne OU un nombre"

string | null — résultat ou absence

Le pattern standard pour exprimer "une valeur qui peut ne pas exister"

// Chercher un utilisateur — peut ne pas exister

function trouverUtilisateur(id: number): string | null {

const users = ["Alice", "Bob"]

return users[id] ?? null // retourne null si introuvable

}

const resultat = trouverUtilisateur(0)

// TypeScript FORCE à vérifier avant d'utiliser

console.log(resultat.toUpperCase()) // âś— Erreur ! peut ĂŞtre null

if (resultat !== null) {

console.log(resultat.toUpperCase()) // âś“ OK ici

}

string | null oblige à gérer le cas "pas de résultat" — TypeScript vous protège des NPE !

Literal Types — union de valeurs précises

On peut unir non seulement des types, mais des valeurs littérales

// Seulement ces 3 valeurs sont acceptées

type Direction = "gauche" | "droite" | "tout droit"

function deplacer(dir: Direction): void {

console.log(`Je vais ${dir}`)

}

deplacer("gauche") // âś“

deplacer("droite") // âś“

deplacer("en arrière") // ✗ Erreur — valeur non autorisée

Autres exemples courants

"pending" | "success" | "error"

"admin" | "user" | "guest"

1 | 2 | 3 | 4 | 5 // note sur 5

Avantage : autocomplétion dans l'IDE + erreur si valeur invalide — plus robuste qu'un simple string

Module 5

Type Narrowing

TypeScript suit ta logique dans les if/else

Le Type Narrowing — TypeScript raisonne avec toi

Quand tu vérifie le type dans un if, TypeScript le sait et restreint le type dans la branche

function afficherLongueur(val: string | number): void {

if (typeof val === "string") {

// Ici TypeScript sait que val est un string

console.log(val.length) // âś“ .length existe sur string

console.log(val.toUpperCase()) // âś“

} else {

// Ici TypeScript sait que val est un number

console.log(val.toFixed(2)) // âś“ .toFixed existe sur number

}

}

Le narrowing est automatique : TypeScript analyse le flux du code et réduit le type possible dans chaque branche

Narrowing avec null

MĂŞme principe pour les unions avec null

function saluer(nom: string | null): string {

if (nom === null) {

// Ici : nom est null

return "Bonjour, inconnu !"

}

// Ici : TypeScript sait que nom est string (null exclu)

return `Bonjour, ${nom} !`

}

typeof

Pour les primitifs

=== null

Pour les valeurs nullables

instanceof

Pour les objets (J4+)

Après un if (nom === null) return, TypeScript retire null du type — c'est l'early return pattern

Pièges courants

✗ ERREUR — Confondre tableau et tuple

const point: number[] = [10, 20]

const x: number = point[0] // ok mais...

const y: number = point[1] // pas de garantie

point.push(30) // 3 éléments maintenant

✓ CORRECT — Tuple pour coordonnées

const point: [number, number] = [10, 20]

const x: number = point[0] // garanti

const y: number = point[1] // garanti

✗ ERREUR — Utiliser sans narrowing

function f(v: string | number) {

v.toUpperCase() // Erreur !

// number n'a pas toUpperCase

}

✓ CORRECT — Narrowing avant usage

function f(v: string | number) {

if (typeof v === "string") {

v.toUpperCase() // âś“

}

}

Points clés à retenir

Tableaux typés

number[] est la convention préférée — plus courte que Array<number> et protège le contenu

Tuples

[string, number] fixe la taille ET le type de chaque position — idéal pour les coordonnées et retours multiples

Union Types

string | null est le pattern standard pour "résultat ou absence de résultat" — très courant en TypeScript

Type Narrowing

Le narrowing est automatique dans les branches du if — TypeScript suit votre logique

La prochaine étape

J4 — Interfaces, types objets, et type guards avancés