Saltar al contenido principal
Volver atrás

TypeScript #5: La Magia de typeof y keyof

#typescript #typeof #keyof

Cómo crear tipos a partir de valores y olvidarse de mantener tipos sincronizados manualmente.

Aquí es donde TypeScript deja de ser “JavaScript con tipos” y se convierte en un superpoder. Hasta ahora hemos definido tipos manualmente. Pero, ¿y si pudiéramos generar los tipos automáticamente desde nuestro código?

typeof: Extrayendo el ADN

En JS, typeof devuelve un string (“string”, “number”, “object”). En TS, si lo usamos en un contexto de tipos, devuelve el tipo completo.

typescript
const settings = {
  theme: "dark",
  notifications: true,
  version: 1.0
};

// En vez de escribir la interfaz manualmente...
// type Settings = { theme: string; notifications: boolean; version: number }; 😴

type Settings = typeof settings; 
// 🪄 ¡Boom! TS acaba de escribir la interfaz por ti.

Esto es brutal para APIs o librerías de terceros (o nuestras propias constantes de configuración). Tenemos una “Single Source of Truth” (Fuente Única de Verdad): el valor. El tipo se adapta solo.

Truco para APIs

Imagina que tienes la respuesta JSON de una API. En lugar de escribir la interfaz a mano, puedes pegar el JSON como una constante (mock) y sacar el tipo de ahí. Así, el ejemplo sirve de documentación y de generador de tipos a la vez.

keyof: Dame las llaves

keyof toma un Tipo y nos devuelve una Unión de sus claves (keys).

typescript
interface Usuario {
  name: string;
  age: number;
  email: string;
}

type UsuarioKeys = keyof Usuario;
// Es equivalente a: "name" | "age" | "email"

¿Para qué sirve? Para que no podamos pedir propiedades que no existen.

typescript
function getProperty(user: Usuario, key: keyof Usuario) {
  return user[key];
}

const me: Usuario = { name: "Paco", age: 39, email: "..." };

getProperty(me, "name"); // ✅
getProperty(me, "password"); // ❌ Error: Argument of type '"password"' is not assignable...

El Combo Definitivo: keyof typeof

Esta es una de las combinaciones más usadas en TypeScript real. Se usa cuando queremos sacar los keys de un objeto/valor que ya existe (no de una interfaz).

  1. typeof objeto -> Nos da el Tipo del objeto.
  2. keyof (Tipo) -> Nos da las keys de ese Tipo.
typescript
const COLORES = {
  rojo: "#FF0000",
  verde: "#00FF00",
  azul: "#0000FF"
} as const; // 'as const' hace que sean literales y readonly

// Queremos un tipo que solo permita "rojo" | "verde" | "azul"
type NombreColor = keyof typeof COLORES;

function pintar(color: NombreColor) { ... }

pintar("rojo"); // ✅
pintar("amarillo"); // ❌
Nota Pro

El as const es vital aquí. Si no lo ponemos, TS inferirá que propiedades son string, y typeof será muy genérico. Con as const le decimos: “¡Esto no cambia, es literal!”.

¡Probémoslo!

Usemos el editor. Creemos un objeto config con varias opciones. Usemos typeof para sacar su tipo y creemos una función que reciba ese tipo.

En la Parte 6 veremos los Generics, la herramienta que nos permite crear componentes y funciones reutilizables que funcionan con cualquier tipo (el famoso <T>).