Fonctions et types retour
Typer les paramètres et le type de retour
En JavaScript, une fonction ne sait pas à l'avance ce qu'on lui passe ni ce qu'elle doit renvoyer. TypeScript corrige ça : tu annotes chaque paramètre et la valeur de retour. Le compilateur détecte immédiatement toute incohérence.
// Paramètres typés + type de retour après les parenthèses
function add(a: number, b: number): number {
return a + b;
}
add(3, 5); // ✅ 8
add("3", 5); // ❌ Erreur : "3" n'est pas un number
add(3, 5, 2); // ❌ Erreur : trop d'arguments
// Type de retour : string
function greet(name: string): string {
return `Bonjour, ${name} !`;
}
const msg: string = greet("Alice"); // ✅
La syntaxe est simple : paramètre: type pour chaque argument,
et ): typeRetour juste avant l'accolade ouvrante.
TypeScript peut souvent inférer le type de retour tout seul — mais l'annoter explicitement rend le code plus lisible et les erreurs plus claires.
Paramètres optionnels et valeurs par défaut
Parfois, certains arguments ne sont pas obligatoires.
TypeScript propose deux solutions : le point d'interrogation ? pour rendre un paramètre optionnel,
et la valeur par défaut = valeur pour fournir un repli.
// Paramètre optionnel avec ?
// suffix est de type string | undefined
function buildUrl(base: string, suffix?: string): string {
return suffix ? `${base}/${suffix}` : base;
}
buildUrl("https://example.com"); // ✅ "https://example.com"
buildUrl("https://example.com", "about"); // ✅ "https://example.com/about"
// Valeur par défaut — le type est inféré automatiquement
function createUser(name: string, role: string = "user"): string {
return `${name} (${role})`;
}
createUser("Bob"); // ✅ "Bob (user)"
createUser("Alice", "admin"); // ✅ "Alice (admin)"
Les paramètres optionnels (?) et les paramètres avec valeur par défaut
doivent toujours se placer après les paramètres obligatoires.
function f(a?: string, b: number) génère une erreur.
Rest parameters — nombre variable d'arguments
Quand le nombre d'arguments n'est pas connu à l'avance, on utilise les rest parameters (...args).
En TypeScript, ils sont annotés comme un tableau.
// ...args reçoit tous les arguments restants sous forme de number[]
function sum(...args: number[]): number {
return args.reduce((acc, n) => acc + n, 0);
}
sum(1, 2, 3); // 6
sum(10, 20, 30, 40); // 100
sum(); // 0 (tableau vide)
// Combinaison : paramètre fixe + rest
function log(prefix: string, ...messages: string[]): void {
messages.forEach(msg => console.log(`[${prefix}] ${msg}`));
}
log("INFO", "Démarrage", "Connexion OK");
// [INFO] Démarrage
// [INFO] Connexion OK
Fonctions fléchées typées
Les fonctions fléchées s'annotent de la même façon.
Le type de retour se place toujours avant la flèche =>.
// Syntaxe classique vs fléchée — même résultat
function double(n: number): number {
return n * 2;
}
const double = (n: number): number => n * 2;
// Fonction fléchée avec corps (plusieurs instructions)
const formatPrice = (price: number, currency: string = "EUR"): string => {
const formatted = price.toFixed(2);
return `${formatted} ${currency}`;
};
console.log(formatPrice(9.9)); // "9.90 EUR"
console.log(formatPrice(42, "USD")); // "42.00 USD"
Types void et never
Deux types spéciaux s'appliquent uniquement aux fonctions :
void— la fonction ne renvoie rien (équivalent d'unreturnabsent ou vide).never— la fonction ne termine jamais son exécution normalement (elle lance une exception ou boucle indéfiniment).
// void : pas de valeur de retour
function printMessage(msg: string): void {
console.log(msg);
// pas de return (ou return; vide)
}
// never : la fonction ne revient jamais
function fail(message: string): never {
throw new Error(message);
// TypeScript sait qu'on n'atteint jamais la suite
}
// never pour une boucle infinie
function runForever(): never {
while (true) {
console.log("tick");
}
}
void et undefined ne sont pas identiques.
Une fonction void peut techniquement renvoyer undefined,
mais son type de retour signifie simplement que la valeur ne doit pas être utilisée.
never est plus strict : le compilateur garantit que l'exécution ne continue jamais.
Surcharge de fonctions (function overloading)
TypeScript permet de déclarer plusieurs signatures pour une même fonction. C'est utile quand la fonction se comporte différemment selon les types de ses arguments.
// 1. Signatures de surcharge (déclarations uniquement)
function format(value: number): string;
function format(value: string): string;
function format(value: boolean): string;
// 2. Implémentation (signature plus large, non visible à l'extérieur)
function format(value: number | string | boolean): string {
if (typeof value === "number") return value.toFixed(2);
if (typeof value === "boolean") return value ? "Oui" : "Non";
return value.trim();
}
format(3.14159); // "3.14"
format(true); // "Oui"
format(" hello "); // "hello"
Types de fonctions
En TypeScript, une fonction est une valeur comme une autre. On peut décrire son type avec la syntaxe fléchée, puis l'utiliser comme annotation de variable ou de paramètre.
// Déclarer un type de fonction avec type alias
type AddFn = (a: number, b: number) => number;
// La variable doit respecter ce contrat
const add: AddFn = (a, b) => a + b; // ✅
const mul: AddFn = (a, b) => a * b; // ✅
const bad: AddFn = (a, b) => `${a}`; // ❌ retourne string, pas number
// Utilisation comme paramètre
function applyTwice(fn: AddFn, x: number): number {
return fn(fn(x, x), fn(x, x));
}
applyTwice(add, 3); // 12
Callbacks typés
Les callbacks sont des fonctions passées en argument à d'autres fonctions. En TypeScript, on les type exactement comme n'importe quel autre paramètre de type fonction.
// Le callback reçoit un number et ne renvoie rien
function processNumbers(
numbers: number[],
callback: (value: number, index: number) => void
): void {
numbers.forEach(callback);
}
processNumbers([10, 20, 30], (val, i) => {
console.log(`[${i}] = ${val}`);
});
// [0] = 10
// [1] = 20
// [2] = 30
// Callback qui renvoie une valeur (ex. transformateur)
type Transformer<T, U> = (item: T) => U;
function mapArray<T, U>(arr: T[], fn: Transformer<T, U>): U[] {
return arr.map(fn);
}
const lengths = mapArray(["hello", "world"], s => s.length);
// lengths est inféré comme number[] → [5, 5]
function f(a: number, b: number): number— annoter paramètres ET retour.- Paramètre optionnel :
x?: string(type devientstring | undefined). - Valeur par défaut :
x: string = "défaut"— toujours après les obligatoires. - Rest params :
...args: number[]— tableau de longueur variable. void: pas de valeur utile renvoyée.never: la fonction ne revient jamais.- Type de fonction :
type AddFn = (a: number, b: number) => number. - Surcharge : plusieurs signatures déclarées, une seule implémentation plus large.
- Les callbacks se typent comme n'importe quel autre paramètre de type fonction.