Tipos anidados y Literal Types en TypeScript
En esta clase nos metemos con dos ideas que te suben el nivel de tipado rápido:
- Tipos anidados para modelar objetos reales (usuario con company, etc.) sin que tu tipo se vuelva un monstruo.
- Literal Types para acotar valores posibles (roles, direcciones, niveles) y que TypeScript no te deje colar cualquier cosa.
Tipos anidados: cuando el mundo real tiene objetos dentro de objetos
Imagina un User que además tiene información de company. Puedes empezar definiéndolo inline, pero enseguida se ve mejor si extraes tipos.
1) Anidar un objeto (y hacerlo opcional)
type User = {
name: string
company?: {
name: string
employees: number
}
}
Si no todos los usuarios tienen company, lo marcas como opcional con ?. Así TypeScript no se queja cuando falte, pero si existe, exige toda la forma del objeto.
2) Extraer el tipo anidado para reutilizarlo
Cuando el objeto anidado crece, lo correcto es sacarlo a un tipo propio:
type Company = {
name: string
employees: number
}
type User = {
name: string
company?: Company
}
Ventajas:
- Reutilización:
Companylo puedes usar en otros sitios. - Legibilidad: el tipo
Userse entiende de un vistazo. - Mantenibilidad: cambias
Companyen un sitio y se refleja en todo.
Literal Types: que el rol no sea “lo que a ti te dé la gana”
Si defines un rol como string, TypeScript te deja meter cualquier cosa y luego vienen los bugs.
type User = {
name: string
role: string // demasiado abierto
}
La solución: restringirlo a valores concretos usando unión de literales (aka Literal Types).
type Role = 'admin' | 'user' | 'editor'
type User = {
name: string
role: Role
}
Ahora:
- Si pones
role: 'asdasd', TypeScript te grita. - Y lo mejor: tienes autocompletado con los valores válidos.
No solo strings: también números y booleanos
Los Literal Types no son solo para texto. Puedes hacer cosas como:
type Answer = 'yes' | 'no' | true | false
type Level = 1 | 2 | 3 | 4
type Direction = 'left' | 'up' | 'down'
Esto se usa muchísimo en videojuegos, estados finitos, configuraciones, flags, etc.
Buenas prácticas rápidas
- Si un objeto anidado empieza a repetirse o crecer → extrae un tipo.
- Si un campo solo puede tener “unos pocos valores” → Literal Types.
- Prefiere nombres semánticos (
Role,Direction,Company) en vez de repetir uniones por todo el código.
Ejercicios
- Crea
type Addressy úsalo dentro deUsercomoaddress?: Address. - Define
type Status = 'idle' | 'loading' | 'success' | 'error'y tipa una funciónsetStatus(status: Status). - Modela un
GameConfigcondifficulty: 1 | 2 | 3ycontrols: 'keyboard' | 'gamepad'.
Resumen
- Los tipos anidados te permiten describir objetos reales sin perder control.
- Extraer tipos (como
Company) hace tu código más limpio y reutilizable. - Los Literal Types evitan valores inválidos y te regalan autocompletado y seguridad extra.