Ajoutez ? après le nom d'un paramètre pour le rendre optionnel. Les appelants peuvent l'omettre, et dans la fonction son type inclut undefined.
TypeScript vérifie le nombre d'arguments : sans le ?, le premier appel serait une erreur de compilation, Expected 2 arguments, but got 1. (TS2554).
Les paramètres optionnels peuvent valoir undefined
Comme un appelant peut l'omettre, le type d'un paramètre optionnel dans la fonction est T | undefined. Avec strictNullChecks, vous devez traiter le cas undefined avant de l'utiliser comme un T.
Le chaînage optionnel (?.) et la coalescence des nuls (??) sont les outils habituels ici. Quand la valeur de repli est fixe, un paramètre par défaut est plus court.
Valeurs par défaut des paramètres
Une valeur par défaut rend le paramètre optionnel pour les appelants et lui donne un type sans undefined dans la fonction. Le type est inféré à partir de la valeur par défaut, l'annotation est donc souvent inutile.
L'appelant voit la signature repeat(text: string, times?: number, separator?: string). Les valeurs par défaut suivent la règle de JavaScript : elles s'appliquent quand l'argument vaut undefined, qu'il soit omis ou passé explicitement, et pas quand il vaut null. Une expression par défaut peut utiliser les paramètres précédents : function range(start: number, end = start + 10).
Règles d'ordre des paramètres
| Déclaration | Compile ? | Remarques |
|---|---|---|
(a: number, b?: number) | Oui | Les paramètres optionnels se placent en dernier |
(a?: number, b: number) | Non | TS1016 : A required parameter cannot follow an optional parameter. |
(a = 0, b: number) | Oui | Mais les appelants doivent écrire f(undefined, 5) pour utiliser la valeur par défaut |
(a: number, ...rest: number[]) | Oui | Un paramètre rest est toujours le dernier |
(a?: number, ...rest: number[]) | Oui | Un optionnel avant un rest est autorisé |
Un paramètre avec valeur par défaut placé avant un paramètre obligatoire est légal mais maladroit. Son type pour les appelants devient number | undefined, et personne n'aime écrire undefined comme bouche-trou. Si vous avez besoin d'un premier paramètre flexible, utilisez plutôt un objet d'options ou la surcharge de fonctions.
Omis ou undefined
x?: number et x: number | undefined se ressemblent et ont le même type dans la fonction. Ils diffèrent pour l'appelant : le premier peut être omis, le second doit être passé.
Utilisez | undefined pour un argument obligatoire qui peut ne pas avoir de valeur, afin que chaque appelant doive y réfléchir. Utilisez ? quand l'omettre est un appel normal. (Le message dit vraiment « 1 arguments » : c'est la formulation de TypeScript.)
Paramètres rest
Un paramètre rest, ...name: T[], rassemble un nombre quelconque d'arguments dans un tableau. Il doit être le dernier paramètre.
Étaler un tableau dans des paramètres fixes est plus strict. Un paramètre rest accepte l'étalement de n'importe quel number[], mais une fonction déclarée (a: number, b: number) n'accepte que l'étalement d'un tuple, car TypeScript doit connaître la longueur :
function point(x: number, y: number) { return { x, y }; }
const list = [3, 4]; // number[]
point(...list);
// error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
const pair = [3, 4] as const; // readonly [3, 4]
point(...pair); // fine
Un paramètre rest peut aussi avoir un type tuple, qui type chaque position : ...args: [name: string, age?: number].
Objets d'options
Dès qu'une fonction a plus de deux ou trois paramètres optionnels, les appelants perdent le fil des positions. Un objet d'options avec des valeurs par défaut donne des arguments nommés, dans n'importe quel ordre.
Le = {} final rend l'objet entier optionnel. Sans lui, fetchData("/a") est une erreur de compilation (Expected 2 arguments, but got 1., TS2554), et en JavaScript pur le même appel lèverait une TypeError à l'exécution, car la déstructuration a besoin d'un objet à lire.
Paramètres optionnels dans les types de callbacks
Dans un type de fonction, ? signifie « celui qui appelle ce callback peut ne pas le passer ». Cela ne signifie pas « le callback peut l'ignorer » : un callback peut toujours ignorer les derniers paramètres. Ne marquez donc pas les paramètres d'un callback comme optionnels juste pour permettre aux gestionnaires de prendre moins d'arguments.
// Too loose: every handler must now cope with index being undefined
type Visit = (item: string, index?: number) => void;
// Right: the caller always passes both; handlers may use only item
type VisitStrict = (item: string, index: number) => void;
const log: VisitStrict = (item) => console.log(item);
Questions fréquentes
Comment rendre un paramètre optionnel en TypeScript ?
Placez un ? après son nom : function greet(name?: string). Les appelants peuvent l'omettre, et dans la fonction son type est string | undefined : vous le vérifiez donc avant de l'utiliser. Donner une valeur par défaut au paramètre, name = "there", le rend aussi optionnel et retire le undefined dans la fonction.
Un paramètre optionnel peut-il précéder un paramètre obligatoire en TypeScript ?
Pas avec ? : (a?: number, b: number) provoque l'erreur TS1016, « A required parameter cannot follow an optional parameter. » Un paramètre avec valeur par défaut peut venir en premier, mais les appelants doivent alors passer undefined explicitement pour utiliser la valeur par défaut : en pratique, les paramètres optionnels et ceux avec valeur par défaut se placent en dernier.
Quelle est la différence entre x?: number et x: number | undefined ?
Dans la fonction, les deux valent number | undefined. La différence se situe à l'appel : avec x?: number, l'argument peut être omis, alors qu'avec x: number | undefined, il doit être passé, même si sa valeur est undefined. L'omettre provoque l'erreur TS2554.
Passer null utilise-t-il la valeur par défaut du paramètre ?
Non. JavaScript n'applique une valeur par défaut que lorsque l'argument vaut undefined (omis ou passé explicitement). null est une valeur, il est donc conservé. De toute façon, TypeScript refuse null pour un paramètre number avec strictNullChecks.
Comment passer un tableau comme arguments séparés en TypeScript ?
Étalez-le : fn(...args). Pour une fonction à paramètres fixes, le tableau doit avoir un type tuple comme [number, number] ou venir d'un as const ; étaler un number[] provoque l'erreur TS2556, car sa longueur est inconnue. Étaler dans un paramètre rest (...values: number[]) fonctionne toujours.