typescript - La tipificación de primitivo a cadena falla con T que extiende null...?
Estoy intentando convertir un primitivo a una representación en cadena, y lo he reducido al siguiente código:
type arg = string | boolean | number | Date | null;
type PrimToString<T> =
| T extends string ? 'string' : never
| T extends boolean ? 'boolean' : never
| T extends number ? 'number' : never
| T extends Date ? 'date' : never
| T extends null ? 'null' : never
;
const a: PrimToString<arg> = 'string'; // Good
const b: PrimToString<arg> = 'boolean'; // Good
const c: PrimToString<arg> = 'number'; // Good
const d: PrimToString<arg> = 'date'; // Good
const e: PrimToString<arg> = 'null'; // Shows Error (below)
var a = 'string';
var b = 'boolean';
var c = 'number';
var d = 'date';
var e = 'null';
// Type '"null"' is not assignable to type '"string" | "number" | "boolean" | "date"'.
Es sorprendente que 'null' no se muestre en absoluto, incluso al pasar el cursor, por ejemplo, sobre const c.
Aquí hay un playground de Typescript que demuestra el problema.
¿Alguien cree que esto es un error? ¿Cómo debería escribir esto de manera diferente?
Respuesta #1
Cuando strictNullChecks está desactivado (que es el caso por defecto), null es un valor especial que se puede asignar a cualquiera de estos valores. Observa:
const str: string = null;
Esto está bien cuando strictNullChecks está desactivado, pero cuando está activado, generará
El tipo '
null' no se puede asignar al tipo 'string'.
De manera similar :
type A = null extends string ? true : false;
Devolverá true cuando strictNullChecks esté deshabilitado, y false cuando esté habilitado.
Así que cuando strictNullChecks está desactivado, string | boolean | number | Date | null es completamente equivalente a string | boolean | number | Date, y tu tipo PrimToString<T> nunca alcanzará el caso final de la unión. Activar esta opción del compilador permitirá que tu código funcione como se espera.
Ver opciones del compilador
Respuesta #2
No es un error, simplemente tienes la configuración de compilador incorrecta. Con la configuración predeterminada, null se puede asignar a cualquier otro tipo, por lo que se simplificará en la unión. Si activas strictNullChecks, entonces el código funciona como se espera: Link
