Consigna: typescript tipar un boolean que discrimine que la siguiente propiedad sea número o fecha
Respuesta:
Para discriminar si una propiedad es de tipo number o Date basándote en un valor booleano (o una condición), la técnica más robusta en TypeScript es usar tipos condicionales con la palabra clave extends. Esto permite definir un tipo que cambia dinámicamente según la estructura de los datos.
Aquí tienes la implementación directa:
// 1. Definir el tipo condicional
// Si T tiene una propiedad 'esNumero' true, devuelve number. Si no, devuelve Date.
type PropiedadDiscriminada = T extends { esNumero: true }
? number
: Date;
// 2. Uso en una función o interfaz
function procesarDato<T extends { esNumero: boolean }>(
datos: T,
valor: PropiedadDiscriminada
): void {
console.log(valor);
}
// Caso A: esNumero es true -> El segundo argumento debe ser number
procesarDato({ esNumero: true }, 42); // ✅ Correcto
// Caso B: esNumero es false -> El segundo argumento debe ser Date
procesarDato({ esNumero: false }, new Date()); // ✅ Correcto
// Caso C: Error de tipo
// procesarDato({ esNumero: false }, 42); // ❌ Error: Type 'number' is not assignable to type 'Date'Explicación clave
extends: Evalúa si el tipo genéricoTcumple con la estructura{ esNumero: true }.?y:: Sintaxis de operador ternario para tipos. Si la condición estrue, el tipo resultante esnumber; si esfalse(o cualquier otro caso), esDate.Discriminación: TypeScript verifica en tiempo de compilación que el valor pasado coincida con el tipo inferido por la condición booleana.
Alternativa: Union Types con Discriminante (Discriminated Unions)
Si prefieres una estructura más explícita para estados complejos, usa uniones discriminadas:
type DatoNumerico = {
tipo: 'numero';
valor: number;
};
type DatoFecha = {
tipo: 'fecha';
valor: Date;
};
type Dato = DatoNumerico | DatoFecha;
function manejarDato(dato: Dato) {
switch (dato.tipo) {
case 'numero':
console.log(dato.valor.toFixed(2)); // TS sabe que es number
break;
case 'fecha':
console.log(dato.valor.toISOString()); // TS sabe que es Date
break;
}
}Esta segunda opción es más segura si necesitas manejar múltiples tipos o lógica compleja, ya que el compilador fuerza el manejo de todos los casos posibles.
Comentarios