Type Script already provide decorators to help developers implement reflection.
If we use the technique decorators, we have to add decorators on the target class during developing.
But is there a way to find members of a specific instance?html
Here is a code to reflect an object instance by using JSON functions.
The limitations:typescript
export class ReflectMemberInfo { constructor(public name:string, public type: string, public isArray: boolean) { } } export class WeekReflector { members: ReflectMemberInfo[] = []; reflect(obj: any): void { JSON.stringify(obj, (key, value) => { if (key == '') { // it is the root object return value; } var isArray = (value instanceof Array); this.members.push(new ReflectMemberInfo(key, typeof(value), isArray)); return null; }); } } // Test class TestObject { memberBoolean: boolean = false; memberNumber: number = 1; memberString: string = "Jack"; // memberSymbol: Symbol = Symbol(); memberUndefined?: string = undefined; // type is undefined memberNull: string | null = null; // type is object memberCannotFound: string; // cannot be reflected memberObject: TestNestedObject = new TestNestedObject(); // type is object memberStringArray: string[] = ["A", "B", "C"]; // type is object memberObjectArray: TestNestedObject[] = [new TestNestedObject(), new TestNestedObject()]; // type is function memberFunction: Function = () => {}; // cannot be reflected public normalFunc(): any { return null; } } class TestNestedObject { nestedNumber: number = 2; nestedString: string = "Mike"; nestedNull: string | null = null; nestedUndefined?: string = undefined; nestedStringArray: string[] = ["A", "B", "C"]; } var reflector = new WeekReflector(); reflector.reflect(new TestObject()); console.log(reflector.members);
[ ReflectMemberInfo { name: 'memberBoolean', type: 'boolean', isArray: false }, ReflectMemberInfo { name: 'memberNumber', type: 'number', isArray: false }, ReflectMemberInfo { name: 'memberString', type: 'string', isArray: false }, ReflectMemberInfo { name: 'memberUndefined', type: 'undefined', isArray: false }, ReflectMemberInfo { name: 'memberNull', type: 'object', isArray: false }, ReflectMemberInfo { name: 'memberObject', type: 'object', isArray: false }, ReflectMemberInfo { name: 'memberStringArray', type: 'object', isArray: true }, ReflectMemberInfo { name: 'memberObjectArray', type: 'object', isArray: true }, ReflectMemberInfo { name: 'memberFunction', type: 'function', isArray: false } ]