Saltar al contenido
webtype.orgDoce conceptos · 2/12

Concepto 2 de 12

Parámetros genéricos

Un parámetro genérico convierte un alias en una función que recibe tipos y devuelve un tipo. En cuanto lo lees así — argumentos dentro, tipo fuera — el resto del sistema de tipos deja de parecer sintaxis y empieza a parecer programación.

Parámetros, valores por defecto y todo lo demás

type Box<T> = { value: T }
type Boxed = Box<string>        // { value: string }

// Defaults work exactly like function parameter defaults.
type List<T, Sep extends string = ','> = { items: T[]; sep: Sep }
type Plain = List<number>       // sep is ','

Los parámetros de tipo son posicionales, pueden tener valores por defecto, y esos valores pueden referirse a parámetros anteriores. El código recursivo a nivel de tipos se apoya en esto constantemente: un acumulador casi siempre es un parámetro con valor por defecto que quien llama nunca pasa.

`extends` aquí significa «debe ser al menos»

type Length<S extends string> = S['length']

Length<'abc'>   // ok
Length<42>      // Error: 42 does not satisfy the constraint 'string'

En una lista de parámetros, `extends` es una restricción: limita lo que se puede pasar. No es herencia, y no significa que el parámetro *sea* ese tipo — solo que lo que llegue es asignable a él.

La misma palabra clave significa algo completamente distinto dentro de un tipo condicional, donde plantea una pregunta en vez de imponer una regla. Distinguirlas por su posición es uno de los obstáculos reales al aprender esto.

El error más común

// Intent: accept any object and read a key from it.
type Get<T, K> = T[K]
//                 ^ Error: type K cannot be used to index type T

// Fixed: constrain K to the keys T actually has.
type Get2<T, K extends keyof T> = T[K]

Sin una restricción el compilador no tiene motivo para creer que `K` es una clave válida, así que se niega. Las restricciones no son decoración — son lo que permite que el cuerpo de un tipo genérico haga algo con sus parámetros.

Para recordar

Lee `type F<A, B> = ...` como una función de tipos a tipos. El `extends` de la lista de parámetros es el control de argumentos en la puerta.