Comprueba si un valor que también puede ser nulo es mayor que 4 en TypeScript
¿Cómo puedo comprobar si un valor que se inicializa como null o número es mayor que 4 en TypeScript? Ver ejemplo.
years: number | null;
esto dará un error de TypeScript "El objeto posiblemente es 'null'."
(years > 4)
Respuesta #1
Supongo que estás preguntando cómo puedes expresar el requisito estático de que un parámetro de función (o valor de retorno, o valor de propiedad de clase) llamado x siempre cumpla ( x es número && x > 4 ) | null.
...que también se conoce como un Tipo de Predicado, Tipo de Refinamiento o Tipo Dependiente.
Desafortunadamente, TypeScript (hasta donde yo sé) aún no admite tipos de refinamiento verdaderos o tipos predicado (aunque sus capacidades de análisis de flujo están casi allí), pero puedes casi lograrlo con una definición de tipo y un guardia de tipo:
type NumberGT4OrNull = null | ( number & { _isGT4: never } );
function isNumberGT4OrNull( x: unknown ): x is NumberGT4OrNull {
if( typeof x === 'number' ) {
return x > 4;
}
return false;
}
- La declaración de tipo
type NumberGT4OrNull=null | number;es demasiado permisiva, ya que coincide con el valor1, por ejemplo. Hacer que sea un tipo suma con un miembro tipado como
neversignifica que ningún valor literal (o cualquier otro valor) posible dentro de TypeScript o JavaScript puede coincidir conNumberGT4OrNull, al menos no sin usar el guarda de tipo personalizadoisNumberGT4OrNull, que evita usar accidentalmente cualquier valor no verificado porisNumberGT4OrNullen un parámetro, valor de retorno o propiedad tipada comoNumberGT4OrNull....excepto por
null, porque en este caso, la palabra clavenullestá fuera del tipo suma connever.- Pero si quieres exigir que incluso los valores
nullsean verificados, entonces usatype NumberGT4OrNull=( null | number ) & { _isGT4: nunca };.
- Pero si quieres exigir que incluso los valores
- ...excepto por
null, porque en este caso, la palabra clavenullestá fuera del tipo suma connever. - Pero si quieres que incluso los valores
nulldeban ser verificados, entonces usatype NumberGT4OrNull=( null | number ) & { _isGT4: never };.
isNumberGT4OrNull, pero esto no es un problema tan grande en el panorama general.Usado así:
function acceptsValue( value: NumberGT4OrNull ): void {
}
//
const userInput = prompt("Enter number");
acceptsValue( userInput ); // Error: userInput is a string
const userInputNumber = parseInt( userInput, 10 );
acceptsValue( userInputNumber ); // Error: userInputNumber is not NumberGT4OrNull
if( isNumberGT4OrNull( userInputNumber ) ) {
acceptsValue( userInputNumber ); // OK! TSC knows `userInputNumber` is `NumberGT4OrNull`.
}
Como se dijo arriba, el uso de never significa que un valor literal no coincidirá, por lo que lo siguiente no funcionará y te dará errores:
acceptsValue( 3 ); // Error
acceptsValue( 4 ); // Error
acceptsValue( 5 ); // Error
acceptsValue( null ); // But this is OK
Pero puedes agregar un conjunto (no exhaustivo) de valores constantes para mayor comodidad si lo deseas:
type NumberGT4OrNull = null | ( number & { _isGT4: never } ) | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16;
// So now, this does work:
acceptsValue( 3 ); // Error
acceptsValue( 4 ); // Error
acceptsValue( 5 ); // OK!
acceptsValue( null ); // Also OK
const n = 17;
acceptsValue( n ); // Error
if( isNumberGT4OrNull( n ) ) {
acceptsValue( n ); // OK!
}
Enlace del parque
Respuesta #2
years podría ser un número, o podría ser null. Y null > 4 no tiene ningún sentido.
Así que antes de hacer eso, tienes que verificar para asegurarte de que en realidad no sea null primero.
if (years !== null) {
const isMoreThanFour = years > 4
}
Parque infantil
