Skip to content

Commit

Permalink
feature(type): treat keyof this as any so that it does not work i…
Browse files Browse the repository at this point in the history
…n a strange unexpected way.

ref #430
  • Loading branch information
marcj committed Apr 12, 2023
1 parent ece8c02 commit e02fa0d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
7 changes: 7 additions & 0 deletions packages/type-compiler/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions packages/type-compiler/tests/transpile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
20 changes: 20 additions & 0 deletions packages/type/tests/type.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1453,3 +1453,23 @@ test('issue-429: invalid function detection', () => {
expect(stringifyResolvedType(typeOf<isFunction>())).toBe('false');
expect(stringifyResolvedType(typeOf<keys>())).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<T> = {[K in keyof T]: T[K] extends ArrowFunction ? K : never}[keyof T];
type keys = MethodKeys<SomeClass>;

//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<keys>())).toBe(`'someFunctionA' | 'someFunctionB' | 'someFunctionC'`);
});

0 comments on commit e02fa0d

Please sign in to comment.