Les motifs de génériques auxquels vous avez recours, regroupés par rôle : déclarer un paramètre de type, le contraindre, lui donner une valeur par défaut, brancher avec un type conditionnel, capturer avec infer et transformer une forme. Chaque ligne associe le motif à un exemple en une ligne.
Un générique est un paramètre de type : un espace réservé pour un type que l’appelant choisit, si bien qu’une même fonction ou un même type convient à plein de formes sans perdre en précision. Lisez <T> comme « pour un certain type T ». La puissance vient de la contrainte de T, du branchement sur T et de la transformation de T. Les motifs ci-dessous forment le vocabulaire de travail.
Tableau de référence · 28 entrées
Génériques TypeScriptExplained
28 of 28 rows
Déclarer
Un paramètre de type choisi par l’appelant.
function first<T>(xs: T[]): T
Plusieurs paramètres de type indépendants.
function pair<T, U>(a: T, b: U): [T, U]
Un second paramètre lié aux clés du premier.
function get<T, K extends keyof T>(o: T, k: K): T[K]
Une classe avec un paramètre de type sur ses champs et ses méthodes.
class Box<T> { value: T }
Une forme d’objet avec un paramètre de type.
interface Result<T> { data: T }
Un paramètre de type sur une fonction fléchée ; la virgule finale empêche les fichiers .tsx de l’interpréter comme du JSX.
const first = <T,>(xs: T[]): T => xs[0]
Contraindre
Exige que T soit assignable à Type.
function len<T extends { length: number }>(x: T)
Restreint T à une clé d’un autre type.
type Keys<O> = keyof O
Restreint T à une classe constructible.
function make<C extends new () => C>(c: C): C
Exige que T satisfasse plusieurs contraintes à la fois.
function log<T extends Error & { code: number }>(e: T)
Restreint à n’importe quoi ; garde le paramètre générique sans le rétrécir.
type Wrap<T> = T extends unknown ? { v: T } : never
Par défaut et inférence
Donne à T une valeur par défaut quand l’appelant l’omet.
function parse<T = string>(): T
Capture un type à l’intérieur d’un conditionnel.
type El<T> = T extends Array<infer I> ? I : never
Déballe un Promise imbriqué jusqu’à son type interne.
type Data = Awaited<Promise<User>>
Capture un morceau d’un type littéral de gabarit.
type Path<S> = S extends `/api/${infer R}` ? R : never
Vérifie toute l’union d’un coup ; un T nu infère un membre à la fois.
type El<T> = [T] extends [Array<infer I>] ? I : never
Conditionnels et mappés
Choisit un type selon que T est assignable à U.
type IsStr<T> = T extends string ? true : false
Construit un nouveau type d’objet en transformant chaque clé de T.
type Frozen<T> = { [K in keyof T]: Readonly<T[K]> }
Un objet dont les clés sont K et les valeurs V.
type Scores = Record<string, number>
Génériques intégrés dérivés des motifs ci-dessus.
type Preview = Pick<User, "id" | "name">
Un T nu avant extends s’exécute une fois par membre de l’union et unit les résultats.
ToArray<'a' | 'b'> = 'a'[] | 'b'[]
Ajoute ou retire des modificateurs sur les clés mappées.
type Req<T> = { [K in keyof T]-?: T[K] }
Les clés d’une valeur d’exécution, sous forme de type.
const opts = { a: 1 }; type K = keyof typeof opts
Construit un type de chaîne à partir d’autres types de chaîne.
type Route = `/users/${string}`
Concatène des types tuples bout à bout.
type Concat<T extends unknown[], U extends unknown[]> = [...T, ...U]
Un type dont la définition se référence lui-même.
type Json = string | number | Json[] | { [k: string]: Json }
Vérifie une valeur contre un type et conserve son type littéral plus étroit.
const c = { dark: "#000" } satisfies Record<string, string>
Conserve le type littéral de l’appelant au lieu de l’élargir (TS 5.0).