Saltar al contenido
webtype.orgDoce conceptos · 6/12

Concepto 6 de 12

Tipos condicionales

Un tipo condicional es el `if` a nivel de tipos. La pregunta que plantea es siempre la misma: ¿es el lado izquierdo asignable al derecho? No «¿son iguales?», no «¿es una instancia de?» — asignable, y en un solo sentido.

Asignabilidad, no igualdad

type A = 'hello' extends string ? true : false   // true
type B = string extends 'hello' ? true : false   // false
type C = never extends string ? true : false     // true — never fits anywhere
type D = { a: 1; b: 2 } extends { a: 1 } ? true : false  // true

Un tipo más estrecho es asignable a uno más amplio, así que la prueba tiene dirección. Un objeto con propiedades de más es asignable a otro con menos, y por eso `extends` no sirve para comprobar que dos tipos objeto tengan la misma forma.

Cuando de verdad necesitas «el mismo tipo», necesitas el helper `Equal` sobre el que se apoya cada comprobación de este sitio — dos condicionales diferidos comparados por identidad, más estricto que la asignabilidad en ambos sentidos.

Las ramas se prueban en orden

type Describe<T> = T extends (...args: never[]) => unknown
  ? 'function'
  : T extends unknown[]
    ? 'array'
    : T extends object
      ? 'object'
      : 'primitive'

Los casos más estrechos deben ir primero. Funciones y arrays son ambos objetos, así que probar `extends object` pronto se los tragaría — la causa clásica de un `DeepReadonly` que destruye en silencio cada función que toca.

El error más común

// Intent: is T exactly string?
type IsString<T> = T extends string ? true : false

IsString<'hello'>  // true — but 'hello' is not string, it is narrower
IsString<any>      // boolean — any matches both branches at once

`extends` responde a «cabe en», así que todo literal de cadena pasa una prueba de `string`. Y `any` es asignable a todo, así que un condicional con `any` devuelve la unión de ambas ramas — un resultado que casi nunca es el que se pretendía.

Para recordar

Los condicionales preguntan por asignabilidad y prueban las ramas en orden. Lo estrecho primero, y recurre a `Equal` en cuanto necesites igualdad real.

Se practica en