Esta pregunta es el análogo directo a la verificación de tipo de clase con TypeScript
Necesito averiguar en tiempo de ejecución si una variable de tipo implementa una interfaz. Aquí está mi código:
interface A{
member:string;
}
var a:any={member:"foobar"};
if(a instanceof A) alert(a.member);
Si ingresa este código en el campo de juegos mecanografiado, la última línea se marcará como un error, "El nombre A no existe en el ámbito actual". Pero eso no es cierto, el nombre existe en el ámbito actual. Incluso puedo cambiar la declaración de la variable var a:A={member:"foobar"};
sin quejas del editor. Después de navegar por la web y encontrar la otra pregunta en SO, cambié la interfaz a una clase pero luego no puedo usar literales de objeto para crear instancias.
Me preguntaba cómo el tipo A podría desaparecer así, pero un vistazo al JavaScript generado explica el problema:
var a = {
member: "foobar"
};
if(a instanceof A) {
alert(a.member);
}
No hay representación de A como interfaz, por lo tanto, no es posible realizar verificaciones de tipo de tiempo de ejecución.
Entiendo que javascript como lenguaje dinámico no tiene concepto de interfaces. ¿Hay alguna forma de escribir check para interfaces?
El autocompletado del campo de escritura mecanografiado revela que el mecanografiado incluso ofrece un método implements
. Como puedo usar lo ?
Respuestas:
Puede lograr lo que desea sin la
instanceof
palabra clave, ya que puede escribir protectores de tipo personalizados ahora:Muchos miembros
Si necesita verificar muchos miembros para determinar si un objeto coincide con su tipo, puede agregar un discriminador. El siguiente es el ejemplo más básico, y requiere que maneje sus propios discriminadores ... necesitaría profundizar en los patrones para asegurarse de evitar discriminadores duplicados.
fuente
isInstanceOfA(instantiatedB)
devolver verdadero, pero desearíaisInstanceOfB(instantiatedA)
devolver falso. Para que esto último ocurra, ¿no debería el discriminador de B no ser 'I-AM-A'?En TypeScript 1.6, la protección de tipo definida por el usuario hará el trabajo.
Y tal como lo mencionó Joe Yang: desde TypeScript 2.0, incluso puede aprovechar el tipo de unión etiquetado.
Y también funciona con
switch
.fuente
object is type
yobject instanceof class
es que, escribir TypeScript es estructural, solo le importa la "forma" en lugar de dónde obtuvo un objeto la forma: un objeto plano o una instancia de una clase, no importa.type
propiedad. En ese caso funciona. Ese ejemplo no muestra este hecho.mecanografiado 2.0 introducir unión etiquetada
Características de Typecript 2.0
fuente
¿Qué hay de los protectores de tipo definidos por el usuario? https://www.typescriptlang.org/docs/handbook/advanced-types.html
fuente
(pet as Fish).swim !== undefined;
hizo.Ahora es posible, acabo de lanzar una versión mejorada del
TypeScript
compilador que proporciona capacidades de reflexión completas. Puede crear instancias de clases de sus objetos de metadatos, recuperar metadatos de constructores de clases e inspeccionar interfaces / clases en tiempo de ejecución. Puedes verlo aquíEjemplo de uso:
En uno de sus archivos de mecanografía, cree una interfaz y una clase que la implemente de la siguiente manera:
ahora imprimamos la lista de interfaces implementadas.
compile con reflec-ts y ejecútelo:
Ver reflection.d.ts para
Interface
detalles de metatipo.ACTUALIZACIÓN: puede encontrar un ejemplo de trabajo completo aquí
fuente
implements
pero quería reconocer su compromiso y no quería ser malo :-)igual que el anterior donde se usaron guardias definidos por el usuario pero esta vez con un predicado de función de flecha
fuente
Aquí hay otra opción: el módulo ts-interface-builder proporciona una herramienta de tiempo de construcción que convierte una interfaz TypeScript en un descriptor de tiempo de ejecución, y ts-interface-checker puede verificar si un objeto lo satisface.
Para el ejemplo de OP,
Primero ejecutaría lo
ts-interface-builder
que produce un nuevo archivo conciso con un descriptor, digamosfoo-ti.ts
, que puede usar así:Puede crear una función de protección de tipo de una línea:
fuente
Me gustaría señalar que TypeScript no proporciona un mecanismo directo para probar dinámicamente si un objeto implementa una interfaz particular.
En cambio, el código TypeScript puede usar la técnica de JavaScript para verificar si un conjunto apropiado de miembros está presente en el objeto. Por ejemplo:
fuente
for (element in obj) {}
) para verificar que los dos objetos tengan elementos similares de tipos similares.Tipo Guardias
fuente
Basado en la respuesta de Fenton , aquí está mi implementación de una función para verificar si un dado
object
tiene las claves yinterface
tiene, total o parcialmente.Dependiendo de su caso de uso, es posible que también deba verificar los tipos de cada una de las propiedades de la interfaz. El siguiente código no hace eso.
Ejemplo de uso:
fuente
fuente
Debido a que el tipo es desconocido en tiempo de ejecución, escribí el siguiente código para comparar el objeto desconocido, no contra un tipo, sino contra un objeto de tipo conocido:
Aquí está el código (interfaz agnóstico) que uso para la comparación profunda:
A continuación se muestra un ejemplo de cómo lo uso.
En este ejemplo, espero que el JSON contenga una matriz de tuplas, de las cuales el segundo elemento es una instancia de una interfaz llamada
User
(que tiene dos elementos opcionales).La verificación de tipos de TypeScript asegurará que mi objeto de muestra sea correcto, luego la función afirmarTypeT verifica que el objeto desconocido (cargado desde JSON) coincida con el objeto de muestra.
Podría invocar una verificación como esta en la implementación de una protección de tipo definida por el usuario.
fuente
Puede validar un tipo TypeScript en tiempo de ejecución utilizando ts-validate-type , de esta manera (aunque requiere un complemento de Babel):
fuente