diff --git a/packages/type-compiler/src/compiler.ts b/packages/type-compiler/src/compiler.ts index c0ce8500a..9e3c56cdb 100644 --- a/packages/type-compiler/src/compiler.ts +++ b/packages/type-compiler/src/compiler.ts @@ -1640,6 +1640,13 @@ export class ReflectionTransformer implements CustomTransformer { //TypeScript does not narrow types down const narrowed = node as TypeOperatorNode; + if (narrowed.type.kind === SyntaxKind.ThisType) { + //for the moment we treat `keyof this` as any, since `this` is not implemented at all. + //this makes it possible that the code above works at least. + program.pushOp(ReflectionOp.any); + break; + } + switch (narrowed.operator) { case SyntaxKind.KeyOfKeyword: { this.extractPackStructOfType(narrowed.type, program); diff --git a/packages/type-compiler/tests/transpile.spec.ts b/packages/type-compiler/tests/transpile.spec.ts index 471ccf2b9..679ed234b 100644 --- a/packages/type-compiler/tests/transpile.spec.ts +++ b/packages/type-compiler/tests/transpile.spec.ts @@ -426,3 +426,14 @@ test('extends with reference to this', () => { //currently broken as it returns LogEntityForSchema.options.entity, probably a bug in TS // expect(res.app).toContain(`() => this.options.entity,`); }); + +test('keyof this expression', () => { + const res = transpile({ + 'app': ` + class Factory { + someFunctionC(input: keyof this) { } + } + ` + }); + console.log(res); +}); diff --git a/packages/type/tests/type.spec.ts b/packages/type/tests/type.spec.ts index f90b0b1db..b7913bef8 100644 --- a/packages/type/tests/type.spec.ts +++ b/packages/type/tests/type.spec.ts @@ -1453,3 +1453,23 @@ test('issue-429: invalid function detection', () => { expect(stringifyResolvedType(typeOf())).toBe('false'); expect(stringifyResolvedType(typeOf())).toBe(`'someFunction'`); }); + +test('issue-430: referring to this', () => { + class SomeClass { + fieldA!: string; + fieldB!: number; + fieldC!: boolean; + + someFunctionA() { } + someFunctionB(input: string) { } + someFunctionC(input: keyof this /* behaves the same with keyof anything */) { } + } + + type ArrowFunction = (...args: any) => any; + type MethodKeys = {[K in keyof T]: T[K] extends ArrowFunction ? K : never}[keyof T]; + type keys = MethodKeys; + + //for the moment we treat `keyof this` as any, since `this` is not implemented at all. + //this makes it possible that the code above works at least. + expect(stringifyResolvedType(typeOf())).toBe(`'someFunctionA' | 'someFunctionB' | 'someFunctionC'`); +});