diff --git a/packages/reflect/src/parser.ts b/packages/reflect/src/parser.ts index 5b1deae0..f69a8c8a 100644 --- a/packages/reflect/src/parser.ts +++ b/packages/reflect/src/parser.ts @@ -209,11 +209,20 @@ function parseMethods(owner: Class): MethodReflection[] { return result } +function isFunction(owner:Class, member:string) { + const descriptor = Object.getOwnPropertyDescriptor(owner, member) + return typeof descriptor?.value === "function" +} + function parseProperties(owner: Class): PropertyReflection[] { const result: PropertyReflection[] = [] const members = getClassMembers(owner) for (const name of members) { - if (typeof (owner as any)[name] === "function" || typeof owner.prototype[name] === "function") continue; + // not static property + if (isFunction(owner, name)) continue; + // not instance property + if (isFunction(owner.prototype, name)) continue; + // static property const classDes = getMemberTypeDescriptor(owner, name) if (classDes && !StaticMemberExclude.includes(name)) { diff --git a/tests/behavior/reflect/__snapshots__/class.spec.ts.snap b/tests/behavior/reflect/__snapshots__/class.spec.ts.snap index c8375ad6..e03b486a 100644 --- a/tests/behavior/reflect/__snapshots__/class.spec.ts.snap +++ b/tests/behavior/reflect/__snapshots__/class.spec.ts.snap @@ -1386,6 +1386,34 @@ Object { } `; +exports[`Class Introspection Should not throw error when inspecting getter/setter which accessing private field 1`] = ` +Object { + "ctor": Object { + "kind": "Constructor", + "name": "constructor", + "parameters": Array [], + }, + "decorators": Array [], + "kind": "Class", + "methods": Array [], + "name": "MyClass", + "properties": Array [ + Object { + "decorators": Array [], + "get": get options, + "kind": "Property", + "name": "options", + "set": undefined, + "type": undefined, + "typeClassification": undefined, + }, + ], + "super": Object, + "type": MyClass, + "typeClassification": "Class", +} +`; + exports[`Class Introspection Should reflect destructed tuple parameters type 1`] = ` Object { "decorators": Array [], diff --git a/tests/behavior/reflect/class.spec.ts b/tests/behavior/reflect/class.spec.ts index d76c86de..a2af81b4 100644 --- a/tests/behavior/reflect/class.spec.ts +++ b/tests/behavior/reflect/class.spec.ts @@ -244,7 +244,7 @@ describe("Class Introspection", () => { it("Should inspect static method", () => { class DummyClass { - static myStaticMethod() {} + static myStaticMethod() { } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -252,7 +252,7 @@ describe("Class Introspection", () => { it("Should inspect static method's parameters ", () => { class DummyClass { - static myStaticMethod(par1:number, par2:string) {} + static myStaticMethod(par1: number, par2: string) { } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -261,7 +261,7 @@ describe("Class Introspection", () => { it("Should inspect static method return type with decorator", () => { class DummyClass { @noop() - static myStaticMethod(par1:number, par2:string):Number { return 1 } + static myStaticMethod(par1: number, par2: string): Number { return 1 } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -270,7 +270,7 @@ describe("Class Introspection", () => { it("Should inspect static method return type with decorator override", () => { class DummyClass { @type([Number]) - static myStaticMethod(par1:number, par2:string):Number[] { return [1] } + static myStaticMethod(par1: number, par2: string): Number[] { return [1] } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -279,7 +279,7 @@ describe("Class Introspection", () => { it("Should inspect static method's parameter type with decorator", () => { class DummyClass { @noop() - static myStaticMethod(par1:number, par2:string) {} + static myStaticMethod(par1: number, par2: string) { } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -287,8 +287,8 @@ describe("Class Introspection", () => { it("Should able to distinguish between static method and instance method with the same name", () => { class DummyClass { - static method() {} - method() {} + static method() { } + method() { } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -297,16 +297,16 @@ describe("Class Introspection", () => { it("Should inspect static property", () => { class DummyClass { @noop() - static myProp:string + static myProp: string } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() }) - + it("Should inspect static property type with decorator override", () => { class DummyClass { @type([Number]) - static myProp:number[] + static myProp: number[] } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -314,8 +314,8 @@ describe("Class Introspection", () => { it("Should inspect static getter and setter", () => { class DummyClass { - static get myProp():number { return 1 } - static set myProp(value:number) { } + static get myProp(): number { return 1 } + static set myProp(value: number) { } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() @@ -324,10 +324,23 @@ describe("Class Introspection", () => { it("Should inspect static getter and setter type", () => { class DummyClass { @noop() - static get myProp():number { return 1 } - static set myProp(value:number) { } + static get myProp(): number { return 1 } + static set myProp(value: number) { } } const meta = reflect(DummyClass) expect(meta).toMatchSnapshot() }) + + it("Should not throw error when inspecting getter/setter which accessing private field", () => { + class MyClass { + #opt = 1 + + get options() { + return this.#opt; + } + } + + const metadata = reflect(MyClass); + expect(metadata).toMatchSnapshot(); + }); }) \ No newline at end of file