Búsqueda de sitios web

Cómo hacer que Typescript entienda que el valor no puede ser nulo después de una llamada a función que lanza un error si el valor es nulo


Tengo una función que verifica si un valor no es nulo, que lanza un error si el valor es nulo. Si no lanza ningún error y devuelve correctamente, sé que el valor no puede ser nulo.

Typescript no parece entender esto sin recurrir a casos if. ¿Hay alguna manera de lograr esto?

Vea el código a continuación para aclaración:

function ensureNotNull<T>(arg: T | null, paramName: string): arg is Exclude<typeof arg, null> {
    if (arg === null) {
        throw new Error(`arg '${paramName}' is null`);
    }

    return true;
}

var value: string | null = null;

function doStuffIfValueNotNull(value: string | null) : void {
    ensureNotNull<string>(value, "value");
    var strLen = value.length; //Error with strictNullChecks
}

Respuesta #1

Podrías hacer que ensureNotNull devuelva el valor no null y asignarlo de nuevo (cambios marcados con ***):

function ensureNotNull<T>(arg: T | null, paramName: string): T {
// *** ------------------------------------------------------^
    if (arg === null) {
        throw new Error(`arg '${paramName}' is null`);
    }

    return arg; // ***
}

var value: string | null = null;

function doStuffIfValueNotNull(value: string | null) : void {
    value = ensureNotNull<string>(value, "value");
//  ^^^^^^^^---- ***
    var strLen = value.length;
}

Alternativamente, if (pero... uf, sugiere que el método devolverá cuando en realidad lanzará):

function doStuffIfValueNotNull(value: string | null) : void {
    if (!ensureNotNull<string>(value, "value")) return;
    var strLen = value.length; //Error with strictNullChecks
}

Respuesta #2

Una manera es convertirlo al tipo esperado.

    ensureNotNull<string>(value, "value");
    var strLen = (value as string).length;

O usa el Operador de Afirmación de No Nulo Postfijo !) (también conocido como "puntuación mágica" :-)

    ensureNotNull<string>(value, "value");
    var strLen = value!.length;

Artículos relacionados