Skip to content

Genéricos de TypeScript explicados

Los patrones de genéricos que usas a diario, agrupados por función: declarar un parámetro de tipo, restringirlo, darle un valor por defecto, ramificar con un condicional, capturar con infer y mapear una forma. Cada fila empareja el patrón con un ejemplo de una línea.

Un genérico es un parámetro de tipo: un marcador de posición para un tipo que elige quien llama, de modo que una sola función o tipo sirve para muchas formas sin perder precisión. Lee <T> como «para algún tipo T». La potencia viene de restringir T, ramificar según él y mapearlo. Los patrones de abajo son el vocabulario de trabajo.

Tabla de referencia · 28 entradas
28 of 28 rows
Declarar
Un parámetro de tipo que elige quien llama.function first<T>(xs: T[]): T
Varios parámetros de tipo independientes.function pair<T, U>(a: T, b: U): [T, U]
Un segundo parámetro ligado a las claves del primero.function get<T, K extends keyof T>(o: T, k: K): T[K]
Una clase con un parámetro de tipo en sus campos y métodos.class Box<T> { value: T }
Una forma de objeto con un parámetro de tipo.interface Result<T> { data: T }
Un parámetro de tipo en una función flecha; la coma final evita que los archivos .tsx lo interpreten como JSX.const first = <T,>(xs: T[]): T => xs[0]
Restringir
Exige que T sea asignable a Type.function len<T extends { length: number }>(x: T)
Restringe T a una clave de otro tipo.type Keys<O> = keyof O
Restringe T a una clase construible.function make<C extends new () => C>(c: C): C
Exige que T cumpla varias restricciones a la vez.function log<T extends Error & { code: number }>(e: T)
Restringe a cualquier cosa; mantiene el parámetro genérico sin estrecharlo.type Wrap<T> = T extends unknown ? { v: T } : never
Por defecto e infer
Da a T un valor por defecto cuando quien llama lo omite.function parse<T = string>(): T
Captura un tipo dentro de un condicional.type El<T> = T extends Array<infer I> ? I : never
Desenvuelve una Promise anidada hasta su tipo interno.type Data = Awaited<Promise<User>>
Captura un fragmento de un tipo literal de plantilla.type Path<S> = S extends `/api/${infer R}` ? R : never
Comprueba la unión completa de una vez; una T desnuda infiere un miembro cada vez.type El<T> = [T] extends [Array<infer I>] ? I : never
Condicionales y mapeados
Elige un tipo según si T es asignable a U.type IsStr<T> = T extends string ? true : false
Construye un nuevo tipo de objeto transformando cada clave de T.type Frozen<T> = { [K in keyof T]: Readonly<T[K]> }
Un objeto cuyas claves son K y cuyos valores son V.type Scores = Record<string, number>
Genéricos integrados derivados de los patrones anteriores.type Preview = Pick<User, "id" | "name">
Una T desnuda antes de extends se ejecuta una vez por miembro de la unión y une los resultados.ToArray<'a' | 'b'> = 'a'[] | 'b'[]
Añade o quita modificadores en las claves mapeadas.type Req<T> = { [K in keyof T]-?: T[K] }
Las claves de un valor en tiempo de ejecución, como tipo.const opts = { a: 1 }; type K = keyof typeof opts
Construye un tipo de cadena a partir de otros tipos de cadena.type Route = `/users/${string}`
Une tipos tupla de extremo a extremo.type Concat<T extends unknown[], U extends unknown[]> = [...T, ...U]
Un tipo cuya definición se refiere a sí mismo.type Json = string | number | Json[] | { [k: string]: Json }
Comprueba un valor contra un tipo y conserva su tipo literal más estrecho.const c = { dark: "#000" } satisfies Record<string, string>
Conserva el tipo literal de quien llama en lugar de ampliarlo (TS 5.0).function first<const T>(xs: readonly T[]): T