Pesquisa de site

Como dizer ao TypeScript que um erro será lançado se um argumento for nulo?


Suponha o seguinte:

const handleParse = (arg: { value: boolean } | null) => {
    if (!arg?.value) {
        throw new Error(`\`arg\` is null`)
    }
    
    return arg.value;
}

Aqui, o Typescript sabe inline que o arg.value retornado sempre estará definido.

No entanto, estou tentando refatorar o erro lançado para um método auxiliar, mas ele está lançando um erro:

const checkDependency = (dependency: any) => {
    if (!dependency) {
        throw new Error(`\`dependency\` is null`)
    }
}

const handleParse = (arg: { value: boolean } | null) => {
    checkDependency(arg)
    
    return arg.value;
//         ^^^ 'arg' is possible null
}

Como posso realizar isso? Eu tentei brincar com o tipo de retorno, mas sem sucesso:

const checkDependency = (dependency: any):  Error | void  => {
    if (!dependency) {
        throw new Error(`\`arg\` is null`)
    }

    return;
}

Resposta #1

Você pode usar uma função de asserção de tipo para isso combinada com um parâmetro de tipo que combinamos com null:

function checkDependency<T>(arg: T | null): asserts arg is T {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^
    if (arg === null) {
        throw new Error(`\`arg\` is null`);
    }
}

Aqui está seu exemplo usando isso:

const handleParse = (arg: { value: boolean } | null) => {
    checkDependency(arg);
    
    return arg.value; // <== No error
};

Exemplo completo no Playground

Funções de asserção de tipo foram adicionadas no TypeScript v3.7. Elas são semelhantes a predicados de tipo, mas fazem exatamente o que você descreve: indicam que, se a função não lançar uma exceção, o tipo é como a função afirma.

Artigos relacionados