Verificação de tipo de classe no TypeScript


240

No ActionScript, é possível verificar o tipo em tempo de execução usando o operador is :

var mySprite:Sprite = new Sprite(); 
trace(mySprite is Sprite); // true 
trace(mySprite is DisplayObject);// true 
trace(mySprite is IEventDispatcher); // true

É possível detectar se uma variável (estende ou) é uma determinada classe ou interface com o TypeScript?

Não consegui encontrar nada sobre isso nas especificações de idioma. Deve estar lá quando se trabalha com classes / interfaces.

Respostas:


319

4.19.4 A instância do operador

O instanceofoperador exige que o operando esquerdo seja do tipo Qualquer, um tipo de objeto ou parâmetro do tipo e o operando direito seja do tipo Qualquer ou um subtipo do tipo de interface 'Função'. O resultado é sempre do tipo primitivo booleano.

Então você poderia usar

mySprite instanceof Sprite;

Observe que esse operador também está no ActionScript, mas não deve mais ser usado lá:

O operador is, que é novo no ActionScript 3.0, permite testar se uma variável ou expressão é membro de um determinado tipo de dados. Nas versões anteriores do ActionScript, o operador instanceof forneceu essa funcionalidade, mas no ActionScript 3.0, o operador instanceof não deve ser usado para testar a associação ao tipo de dados. O operador is deve ser usado em vez da instância do operador para verificação manual do tipo, porque a expressão x instanceof y apenas verifica a cadeia de protótipos de x para a existência de y (e no ActionScript 3.0, a cadeia de protótipos não fornece uma imagem completa hierarquia de herança).

O TypeScript instanceofcompartilha os mesmos problemas. Como é uma linguagem que ainda está em desenvolvimento, recomendo que você apresente uma proposta dessa instalação.

Veja também:


54

O TypeScript tem uma maneira de validar o tipo de uma variável em tempo de execução. Você pode adicionar uma função de validação que retorna um predicado de tipo . Portanto, você pode chamar essa função dentro de uma instrução if e garantir que todo o código desse bloco seja seguro para usar como o tipo que você pensa que é.

Exemplo dos documentos TypeScript:

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

// Both calls to 'swim' and 'fly' are now okay.
if (isFish(pet)) {
  pet.swim();
}
else {
  pet.fly();
}

Veja mais em: https://www.typescriptlang.org/docs/handbook/advanced-types.html


29
Isso não é datilografia em tempo de execução, é apenas verificar se um objeto tem uma determinada propriedade. Isso pode ser bom para tipos de união, portanto funciona para esse caso específico, mas não é realmente possível criar um "isThingy" para tudo isso. Além disso, se peixes e pássaros pudessem nadar, você está condenado. Eu estou feliz que eu estou usando Haxe que tem uma verificação de tipo de confiança que você pode fazer Std.is(pet, Fish), que funciona em tipos, as interfaces etc.
Mark Knol

4
Achei esta resposta útil, mas acho que você poderia ajustá-la para ser um pouco mais precisa. O isFishpróprio é o predicado que é criado, e seu corpo não precisa ser um predicado de uma linha. A vantagem disso é que o compilador entende em tempo de compilação as funções possíveis apropriadas, mas seu código interno isFishé executado em tempo de execução. Você pode até fazer com que o guarda contenha uma instanceofdeclaração, por exemplo return pet instanceof Fish(supondo que seja uma classe e não uma interface), mas isso seria desnecessário, pois o compilador entende instanceofdiretamente.

4
isso também é chamado de "Guardas de tipo definido pelo usuário", consulte basarat.gitbooks.io/typescript/content/docs/types/…
Julian

@ MarkKnol, na verdade, é a verificação do tempo de execução, mas traz à máquina de escrever a capacidade de entender também o tipo inferido (o que significa: você pode confiar em mim, esse será do tipo X ou Y, porque eu o testarei em tempo de execução).
Flavien Volken

3
Você pode considerar o uso, (pet as Fish)pois o tslinter irá reclamar (<Fish>pet). Veja tslint doc
Bryan

1

Você pode usar o instanceofoperador para isso. Do MDN:

O operador instanceof testa se a propriedade prototype de um construtor aparece em qualquer lugar da cadeia de protótipos de um objeto.

Se você não souber o que são protótipos e cadeias de protótipos, recomendo que procure. Também aqui está um exemplo de JS (TS funciona de maneira semelhante a esse respeito) que pode esclarecer o conceito:

    class Animal {
        name;
    
        constructor(name) {
            this.name = name;
        }
    }
    
    const animal = new Animal('fluffy');
    
    // true because Animal in on the prototype chain of animal
    console.log(animal instanceof Animal); // true
    // Proof that Animal is on the prototype chain
    console.log(Object.getPrototypeOf(animal) === Animal.prototype); // true
    
    // true because Object in on the prototype chain of animal
    console.log(animal instanceof Object); 
    // Proof that Object is on the prototype chain
    console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true
    
    console.log(animal instanceof Function); // false, Function not on prototype chain
    
    

A cadeia de protótipos neste exemplo é:

animal> Animal.prototype> Object.prototype

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.