Pesquisa de site

typescript - Quando um predicado 'is' seria necessário, em vez de usar o operador 'in'?


De acordo com a documentação do TypeScript, podemos usar TypeGuards para diferenciar entre tipos.

A documentação fornece exemplos usando o predicado is, e usando o operador in.

é predicado:

function isFish(pet: Fish | Bird): pet is Fish {
    return (pet as Fish).swim !== undefined;
}

if (isFish(pet)) {
    pet.swim();
}
else {
    pet.fly();
}

operador in:

function move(pet: Fish | Bird) {
    if ("swim" in pet) {
        return pet.swim();
    }
    return pet.fly();
}

O operador in parece muito mais conciso e simples - embora talvez puxar explicitamente a diferenciação de tipo para uma função seja útil e mais fácil de manter a longo prazo.

Existem casos em que o predicado is pode diferenciar entre tipos onde o operador in não consegue?

Resposta #1

O operador in é apenas uma maneira de restringir o tipo de uma variável. Você pode escrever guardas de tipo usando qualquer verificação que quiser:

type JSONPrimitive = number | string | boolean | null;

function isJsonPrimitive(x: any): x is JSONPrimitive {
    return x === null
        || typeof x === 'number'
        || typeof x === 'string'
        || typeof x === 'boolean';
}

Ou :

interface TreeNode {
    value: number;
    left: TreeNode | null;
    right: TreeNode | null;
}
type InternalNode = TreeNode & ({ left: TreeNode } | { right: TreeNode });

function isInternalNode(node: TreeNode): node is InternalNode {
    return node.left !== null || node.right !== null;
}

Nenhum desses exemplos pode ser reescrito de forma equivalente usando o operador in.

Dito isso, os guardas de tipo definidos pelo usuário são semelhantes às asserções de tipo, no sentido de que o Typescript não verifica a sua correção. Portanto, você pode usar literalmente qualquer lógica que desejar na implementação do seu guarda de tipo; até mesmo um return true; incondicional é permitido.