Menu

Utility types TypeScript : la liste complète avec exemples

Tous les utility types intégrés à TypeScript au même endroit : Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ReturnType, Awaited, les types de chaîne et d'autres, chacun avec une description en une ligne et un exemple exécutable.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Les utility types sont des types génériques intégrés à TypeScript qui transforment un type en un autre. Au lieu d'écrire un second type User avec tous les champs optionnels, vous écrivez Partial<User> ; au lieu de copier trois champs, Pick<User, "id" | "name">. Ils sont globaux, aucun import n'est donc nécessaire.

Quand User change, les quatre types dérivés suivent. La bibliothèque standard de TypeScript (lib.es5.d.ts) déclare 22 utility types. Les sections ci-dessous les listent tous, regroupés selon le genre de type sur lequel ils agissent, avec un lien vers la page détaillée quand elle existe.

Types objets : Partial, Required, Readonly, Pick, Omit, Record

Utility typeCe qu'il faitExemple
Partial<T>rend toutes les propriétés optionnellesPartial<User> pour les données d'une mise à jour
Required<T>rend toutes les propriétés obligatoires (retire ?)Required<Config> une fois les valeurs par défaut appliquées
Readonly<T>rend toutes les propriétés readonlyReadonly<State>
Pick<T, K>ne garde que les clés KPick<User, "id" | "name">
Omit<T, K>retire les clés KOmit<User, "password">
Record<K, V>un type objet avec des clés K et des valeurs VRecord<"en" | "de", string>

Required<T> est l'inverse de Partial<T> ; la page Partial couvre les deux, y compris le undefined explicite qu'un spread comme celui-ci laisse passer.

Types union : Exclude, Extract, NonNullable

Utility typeCe qu'il faitExemple
Exclude<U, M>retire les membres de l'union affectables à MExclude<"a" | "b" | "c", "a"> vaut "b" | "c"
Extract<U, M>garde les membres de l'union affectables à MExtract<string | number, number> vaut number
NonNullable<T>retire null et undefinedNonNullable<string | null> vaut string

Ces trois types agissent sur des unions, pas sur des objets. C'est la différence essentielle avec Pick et Omit, qui prennent un type objet et une liste de ses clés.

Types de fonctions et de classes : Parameters, ReturnType et autres

Utility typeCe qu'il faitExemple
ReturnType<F>le type de retour d'un type fonctionReturnType<typeof createStore>
Parameters<F>les types des paramètres sous forme de tupleParameters<typeof fetchPage>[0]
ConstructorParameters<C>les paramètres du constructeur d'une classe sous forme de tupleConstructorParameters<typeof Point>
InstanceType<C>le type d'instance que crée un constructeurInstanceType<typeof Point>
ThisParameterType<F>le type du paramètre this d'une fonctionThisParameterType<typeof greet>
OmitThisParameter<F>le type fonction sans son paramètre thisle type de greet.bind(obj)
ThisType<T>fixe le type de this dans les méthodes d'un littéral objetutilisé avec noImplicitThis dans les API de type builder
NoInfer<T>empêche un paramètre de type d'être inféré depuis cette positionfallback: NoInfer<C>

typeof createOrder est nécessaire parce que ces utilitaires prennent un type, et createOrder est une valeur. Il en va de même pour les classes : typeof Point est le type du constructeur, alors que Point seul, employé comme type, désigne déjà le type d'instance.

NoInfer contrôle d'où un générique tire son type :

Sans NoInfer, TypeScript inférerait C à partir des deux arguments et l'élargirait en "red" | "green" | "blue", si bien que la faute de frappe dans la valeur de repli serait acceptée.

Types de chaîne : Uppercase, Lowercase, Capitalize, Uncapitalize

Utility typeCe qu'il faitExemple
Uppercase<S>met un type littéral de chaîne en majusculesUppercase<"get"> vaut "GET"
Lowercase<S>le met en minusculesLowercase<"GET"> vaut "get"
Capitalize<S>met le premier caractère en majusculeCapitalize<"name"> vaut "Name"
Uncapitalize<S>met le premier caractère en minusculeUncapitalize<"Name"> vaut "name"

Ces quatre types sont intégrés au compilateur au lieu d'être écrits en TypeScript, et ils sont surtout utiles dans les template literal types, comme `on${Capitalize<E>}` pour des noms de gestionnaires d'événements.

Promesses : Awaited

Utility typeCe qu'il faitExemple
Awaited<T>le type obtenu avec await, en déballant les promesses imbriquéesAwaited<Promise<Promise<number>>> vaut number

Awaited<ReturnType<typeof fn>> est la façon standard de nommer le type du résultat d'une fonction async sans le déclarer à part.

Combiner les utility types

Les utility types s'imbriquent. Quelques combinaisons reviennent assez souvent pour valoir d'être connues par cœur :

Lisez un utility type imbriqué de l'intérieur vers l'extérieur : Readonly<Pick<Post, "id" | "title">> garde d'abord deux propriétés, puis les passe en lecture seule. Les mêmes briques permettent de construire un helper PartialBy qui ne rend optionnelles que certaines clés ; la page Partial l'écrit en entier.

Les utility types ne font rien à l'exécution

Chaque utility type est effacé à la compilation. Une valeur typée Omit<User, "password"> peut encore contenir un mot de passe à l'exécution si l'objet d'origine en avait un :

Le type limite seulement ce que votre code a le droit de lire. Pour retirer un champ des données, déstructurez-le comme dans les dernières lignes, et pour empêcher la mutation à l'exécution utilisez Object.freeze, pas Readonly. Les types intégrés sont des mapped types et des types conditionnels d'une ligne, les mêmes outils vous permettent donc d'écrire les vôtres.

Questions fréquentes

Que sont les utility types en TypeScript ?

Des types génériques fournis avec TypeScript qui transforment d'autres types : Partial<T> rend toutes les propriétés optionnelles, Pick<T, K> en garde certaines, ReturnType<F> récupère le type de retour d'une fonction, etc. Ils sont déclarés dans la bibliothèque standard, on les utilise donc sans rien importer.

Faut-il importer les utility types ?

Non. Partial, Omit, Record, ReturnType et les autres sont des types globaux issus des fichiers de bibliothèque intégrés à TypeScript. Écrivez Partial<User> n'importe où : ni import ni paquet npm n'est nécessaire.

Quels utility types sont intégrés à TypeScript ?

22, tous déclarés dans lib.es5.d.ts : Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ConstructorParameters, ReturnType, InstanceType, ThisParameterType, OmitThisParameter, ThisType, NoInfer, Awaited, Uppercase, Lowercase, Capitalize et Uncapitalize.

Les utility types modifient-ils les objets à l'exécution ?

Non. Ils ne décrivent que des types et sont effacés du JavaScript produit. Omit<User, "password"> ne supprime pas la propriété password, et Readonly<T> ne gèle rien. Pour modifier l'objet réel, écrivez le code : une déstructuration avec rest, Object.freeze, etc.

Peut-on écrire ses propres utility types ?

Oui. Ceux qui sont intégrés sont du TypeScript ordinaire : la plupart sont des mapped types ou des types conditionnels d'une ligne dans lib.es5.d.ts. type Nullable<T> = { [K in keyof T]: T[K] | null } est un utility type personnalisé écrit de la même manière.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER