Búsqueda de sitios web

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 valor 1, por ejemplo.
  • Hacer que sea un tipo suma con un miembro tipado como never significa que ningún valor literal (o cualquier otro valor) posible dentro de TypeScript o JavaScript puede coincidir con NumberGT4OrNull, al menos no sin usar el guarda de tipo personalizado isNumberGT4OrNull, que evita usar accidentalmente cualquier valor no verificado por isNumberGT4OrNull en un parámetro, valor de retorno o propiedad tipada como NumberGT4OrNull.

    • ...excepto por null, porque en este caso, la palabra clave null está fuera del tipo suma con never.

      • Pero si quieres exigir que incluso los valores null sean verificados, entonces usa type NumberGT4OrNull=( null | number ) & { _isGT4: nunca };.
      • ...excepto por null, porque en este caso, la palabra clave null está fuera del tipo suma con never.
      • Pero si quieres que incluso los valores null deban ser verificados, entonces usa type NumberGT4OrNull=( null | number ) & { _isGT4: never };.

    • El inconveniente es que no puedes no usar 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

Artículos relacionados