Verificación de tipo de clase en TypeScript


240

En ActionScript, es posible verificar el tipo en tiempo de ejecución utilizando el operador is :

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

¿Es posible detectar si una variable (se extiende o) es una determinada clase o interfaz con TypeScript?

No pude encontrar nada al respecto en las especificaciones del idioma. Debería estar allí cuando se trabaja con clases / interfaces.

Respuestas:


319

4.19.4 La instancia del operador

El instanceofoperador requiere que el operando izquierdo sea del tipo Any, un tipo de objeto o un tipo de parámetro de tipo, y el operando derecho sea del tipo Any o un subtipo del tipo de interfaz 'Función'. El resultado es siempre del tipo primitivo booleano.

Entonces podrías usar

mySprite instanceof Sprite;

Tenga en cuenta que este operador también está en ActionScript, pero ya no debería usarse allí:

El operador is, que es nuevo para ActionScript 3.0, le permite probar si una variable o expresión es miembro de un tipo de datos determinado. En versiones anteriores de ActionScript, el operador de instancia de proporcionaba esta funcionalidad, pero en ActionScript 3.0 el operador de instancia de no se debe usar para probar la pertenencia al tipo de datos. Se debe usar el operador is en lugar del operador instanceof para la verificación manual de tipos, porque la expresión x instanceof y simplemente verifica la cadena prototipo de x para la existencia de y (y en ActionScript 3.0, la cadena prototipo no proporciona una imagen completa de la jerarquía de herencia).

TypeScript instanceofcomparte los mismos problemas. Como es un lenguaje que todavía está en desarrollo, le recomiendo que presente una propuesta de dicha instalación.

Ver también:


54

TypeScript tiene una forma de validar el tipo de una variable en tiempo de ejecución. Puede agregar una función de validación que devuelva un predicado de tipo . Por lo tanto, puede llamar a esta función dentro de una instrucción if y asegurarse de que todo el código dentro de ese bloque sea seguro de usar como el tipo que cree que es.

Ejemplo de los documentos de 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();
}

Ver más en: https://www.typescriptlang.org/docs/handbook/advanced-types.html


29
Esto no es un control de tipo de tiempo de ejecución, solo está verificando si un objeto tiene cierta propiedad. Esto puede ser bueno para los tipos de unión, por lo que funciona para este caso específico, pero en realidad no es factible crear un "isThingy" para todo esto. Además, si tanto los peces como las aves pudieran nadar, estás condenado. Me alegro de estar usando Haxe, que tiene una verificación de tipo confiable para que pueda hacerlo Std.is(pet, Fish), que funciona en tipos, interfaces, etc.
Mark Knol

44
Esta respuesta me pareció útil, pero creo que podría ajustarla para ser un poco más precisa. El isFishsí mismo es el predicado que se crea, y su cuerpo no tiene que ser un predicado de una sola línea. La ventaja de esto es que el compilador comprende en tiempo de compilación las funciones posibles apropiadas, pero su código interno isFishse ejecuta en tiempo de ejecución. Incluso podría hacer que el protector contenga una instanceofdeclaración, por ejemplo return pet instanceof Fish(suponiendo que sea una clase y no una interfaz), pero esto sería innecesario ya que el compilador entiende instanceofdirectamente.

44
esto también se llama "Guardias de tipo definidos por el usuario", vea basarat.gitbooks.io/typescript/content/docs/types/…
Julian

@MarkKnol en realidad está comprobando el tiempo de ejecución, pero también ofrece la capacidad de comprender el tipo inferido (lo que significa que puede confiar en mí, será tipo X o Y porque lo probaré en tiempo de ejecución).
Flavien Volken

3
Es posible que desee considerar el uso (pet as Fish)ya que el tslinter se quejará (<Fish>pet). Ver tslint doc
Bryan

1

Puede usar el instanceofoperador para esto. De MDN:

El operador instanceof prueba si la propiedad prototipo de un constructor aparece en algún lugar de la cadena prototipo de un objeto.

Si no sabe qué prototipos y cadenas de prototipos son, le recomiendo que lo busque. También aquí hay un ejemplo de JS (TS funciona de manera similar a este respecto) que podría aclarar el concepto:

    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
    
    

La cadena prototipo en este ejemplo es:

animal> Animal.prototype> Object.prototype

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.