interfaz interfaces instanciar inicializar herencia clases clase typescript reflection

instanciar - interfaces o clases typescript



Obtener propiedades de una clase usando Typescript (4)

¿Hay alguna forma de obtener los nombres de propiedades de clase en TypeScript? En el ejemplo, me gustaría ''describir'' la clase A o cualquier clase y obtener una matriz de sus propiedades (¿quizás solo una pública?), ¿Es posible? ¿O debería instanciar el objeto primero?

class A { private a1; private a2; /** Getters and Setters */ } class Describer<E> { toBeDescribed:E ; describe(): Array<string> { /** * Do something with ''toBeDescribed'' */ return [''a1'', ''a2'']; //<- Example } } let describer = new Describer<A>(); let x= describer.describe(); /** x should be [''a1'', ''a2''] */


Algunas respuestas son parcialmente incorrectas, y algunos hechos en ellas también son parcialmente incorrectos.

Responde tu pregunta: ¡Sí! Usted puede.

En mecanografiado

class A { private a1; private a2; }

Genera el siguiente typescriptlang.org/play/… en Javascript:

var A = /** @class */ (function () { function A() { } return A; }());

como dijo @Erik_Cupal, simplemente puedes hacer:

let a = new A(); let array = return Object.getOwnPropertyNames(a);

Pero esto es incompleto . ¿Qué pasa si tu clase tiene un constructor personalizado? Necesitas hacer un truco con Typescript porque no se compilará. Es necesario asignar como cualquier:

let className:any = A; let a = new className();// the members will have value undefined

Una solución general será:

class A { private a1; private a2; constructor(a1:number, a2:string){ this.a1 = a1; this.a2 = a2; } } class Describer{ describeClass( typeOfClass:any){ let a = new typeOfClass(); let array = Object.getOwnPropertyNames(a); return array;//you can apply any filter here } }

Para una mejor comprensión esto hará referencia dependiendo del contexto.


Este código de TypeScript

class A { private a1; public a2; }

compila a este código de JavaScript

class A { }

Esto se debe a que las propiedades en JavaScript comienzan a existir solo después de que tengan algún valor. Tienes que asignar algún valor a las propiedades.

class A { private a1 = ""; public a2 = ""; }

se compila a

class A { constructor() { this.a1 = ""; this.a2 = ""; } }

Aún así, no puede obtener las propiedades de la mera clase (solo puede obtener métodos del prototipo). Debes crear una instancia. A continuación, obtiene las propiedades llamando a Object.getOwnPropertyNames() .

let a = new A(); let array = return Object.getOwnPropertyNames(a); array[0] === "a1"; array[1] === "a2";

Aplicado a tu ejemplo.

class Describer { static describe(instance): Array<string> { return Object.getOwnPropertyNames(instance); } } let a = new A(); let x = Describer.describe(a);


Otra solución, simplemente puede iterar sobre las claves del objeto, debe crear una instancia del objeto primero:

printTypeNames<T>(obj: T) { const objectKeys = Object.keys(obj) as Array<keyof T>; for (let key of objectKeys) { console.Log(''key:'' + key); } }


Solo por diversión

class A { private a1 = void 0; private a2 = void 0; } class B extends A { private a3 = void 0; private a4 = void 0; } class C extends B { private a5 = void 0; private a6 = void 0; } class Describer { private static FRegEx = new RegExp(/(?:this/.)(.+?(?= ))/g); static describe(val: Function, parent = false): string[] { var result = []; if (parent) { var proto = Object.getPrototypeOf(val.prototype); if (proto) { result = result.concat(this.describe(proto.constructor, parent)); } } result = result.concat(val.toString().match(this.FRegEx) || []); return result; } } console.log(Describer.describe(A)); // ["this.a1", "this.a2"] console.log(Describer.describe(B)); // ["this.a3", "this.a4"] console.log(Describer.describe(C, true)); // ["this.a1", ..., "this.a6"]

Actualización: si está utilizando constructores personalizados, esta funcionalidad se interrumpirá.