Modelar tipos de dominio en TypeScript con uniones discriminadas
Rediseña los tipos de tu dominio en TypeScript para que los estados imposibles no compilen: uniones discriminadas, tipos de marca para IDs, switch exhaustivo y validación en los límites. Pensado para ChatGPT, Claude, Gemini y Microsoft Copilot. Incluye 3 variables personalizables y se copia gratis en un clic.
Avanzado · Código · Pendiente de revisión editorial
Prompt
Actúa como experto en TypeScript y diseño guiado por tipos que prioriza la claridad sobre los trucos.
Contexto:
- Dominio: {{dominio}}
- Tipos actuales (si los hay): {{tipos_actuales}}
- Dónde se usan: {{uso}}
Si no está claro qué transiciones entre estados son válidas o qué campos existen en cada estado, pregúntamelo antes de diseñar.
Entregables:
1. Diagnóstico de los tipos actuales: qué combinaciones imposibles permiten (por ejemplo, un pedido «enviado» sin fecha de envío) y qué errores pueden provocar.
2. El nuevo modelo: uniones discriminadas por un campo literal, campos presentes solo en el estado que les corresponde, `readonly` donde tenga sentido y tipos de marca para identificadores que no deben mezclarse.
3. Funciones de transición tipadas entre estados que solo acepten el estado de origen válido.
4. Un `switch` exhaustivo con comprobación `never` y un ejemplo del error de compilación que aparece al añadir un estado nuevo sin tratarlo.
5. Validación en los límites del sistema (API, formularios, almacenamiento) con un esquema del que se derive el tipo, para que tipo y validación no diverjan.
6. Tests de tipos con `@ts-expect-error` o `expectTypeOf` que demuestren que los estados imposibles no compilan.
7. Cuándo este modelo es excesivo y bastaría con algo más simple.
Restricciones:
- Prefiere uniones de literales a `enum`, salvo que expliques por qué conviene un enum.
- Nada de tipos condicionales o genéricos complejos si no aportan algo claro; el código debe poder leerlo un desarrollador intermedio.
- No inventes reglas de negocio: marca con [COMPLETAR] las que debo confirmar.
Formato: diagnóstico, código en bloques con nombre de archivo y una tabla de estados y transiciones.Cómo usarlo
- Describe los estados reales de tu entidad y qué datos tiene cada uno. 2. Pega los tipos actuales si existen. 3. Sustituye los tipos poco a poco y deja que el compilador te señale los usos que hay que adaptar.
Ejemplo de uso
Dominio: pedidos de una tienda online con estados pendiente, pagado, enviado, entregado y cancelado · Tipos actuales: interfaz Pedido con todos los campos opcionales · Uso: estado de la interfaz y respuestas de API.
Resultado de ejemplo
Diagnóstico
estado: string con campos opcionales permite combinaciones imposibles: un pedido 'enviado' sin numeroSeguimiento o uno 'cancelado' con fechaPago y sin motivo. Cada componente acaba comprobando ?. por todas partes.
pedido.ts
export type PedidoId = string & { readonly __marca: 'PedidoId' };
type Base = { readonly id: PedidoId };
export type Pedido =
| (Base & { estado: 'pendiente' })
| (Base & { estado: 'pagado'; fechaPago: Date })
| (Base & { estado: 'enviado'; fechaPago: Date; numeroSeguimiento: string })
| (Base & { estado: 'entregado'; fechaPago: Date; numeroSeguimiento: string })
| (Base & { estado: 'cancelado'; motivoCancelacion: string });
type EnEstado<E extends Pedido['estado']> = Extract<Pedido, { estado: E }>;
export function enviar(pedido: EnEstado<'pagado'>, numeroSeguimiento: string): EnEstado<'enviado'> {
return { ...pedido, estado: 'enviado', numeroSeguimiento };
}
export function etiqueta(pedido: Pedido): string {
switch (pedido.estado) {
case 'pendiente': return 'Pendiente de pago';
case 'pagado': return 'Pagado';
case 'enviado': return `Enviado (${pedido.numeroSeguimiento})`;
case 'entregado': return 'Entregado';
case 'cancelado': return `Cancelado: ${pedido.motivoCancelacion}`;
default: {
const exhaustivo: never = pedido;
return exhaustivo;
}
}
}
Si mañana añades 'devuelto' y no lo gestionas, la línea never deja de compilar. Por confirmar: ¿se puede cancelar un pedido ya pagado? [COMPLETAR]…
Datos clave
- Categoría
- Programación y desarrollo · TypeScript
- Tipo de resultado
- Código
- Nivel
- Avanzado
- Pensado para
- ChatGPT, Claude, Gemini y Microsoft Copilot
- Verificado en
- Pendiente de verificación editorial
- Variables
- Dominio, Tipos actuales y Dónde se usan
- Idioma
- Español
- Precio
- Gratis, sin registro
- Actualizado
- 07/11/2026
Preguntas frecuentes
¿Qué es una unión discriminada?
Un tipo formado por varias variantes que comparten un campo literal, como estado: «pagado» o «enviado». TypeScript usa ese campo para saber qué otros campos existen en cada variante.
¿Para qué sirven los tipos de marca en los IDs?
Para que el compilador impida pasar un IdCliente donde se espera un IdPedido aunque ambos sean strings. Evitan errores silenciosos difíciles de detectar en revisión.
¿Para qué sirve este prompt?
Rediseña los tipos de tu dominio en TypeScript para que los estados imposibles no compilen: uniones discriminadas, tipos de marca para IDs, switch exhaustivo y validación en los límites.
¿Con qué herramientas de IA funciona?
Está pensado para ChatGPT, Claude, Gemini y Microsoft Copilot. Todavía no lo hemos verificado en estas herramientas, por lo que los resultados pueden variar entre ellas.
¿Cómo personalizo el prompt?
Pulsa «Personalizar» y rellena las variables (Dominio, Tipos actuales y Dónde se usan). El texto se actualiza al instante y después puedes copiarlo con un clic. Los valores se guardan solo en tu navegador.
¿Necesito experiencia para usarlo?
Es de nivel avanzado: está pensado para personas con experiencia en el tema que sepan evaluar y ajustar el resultado.
¿Este prompt es gratis?
Sí. Todos los prompts de HomeCasa Prompts son gratuitos, sin registro ni suscripción. Puedes usarlos también en proyectos profesionales.
¿Puedo fiarme del resultado de la IA?
Úsalo como un borrador de calidad: revisa siempre datos, cifras y afirmaciones importantes antes de publicarlos o tomar decisiones.