deepkit-framework
deepkit-framework copied to clipboard
Incorrect narrowing of functions with `keyof` parameters
When omitting [props whose values are functions] from a type, if the function includes a keyof X parameter, the TS type is correctly narrowed, but the runtime type still includes that prop.
Sandbox: https://replit.com/@fergusean/DKTypeIssueDemo2
Code:
import { typeOf, ReflectionKind } from '@deepkit/type';
export class SomeClass {
fieldA!: string;
fieldB!: number;
fieldC!: boolean;
someFunctionA() { }
someFunctionB(input: string) { }
someFunctionC(input: keyof this /* behaves the same with keyof anything */) { }
}
export type ArrowFunction = (...args: any) => any;
type MethodKeys<T> = {
[K in keyof T]: T[K] extends ArrowFunction ? K : never
}[keyof T];
export type EntityFields<T extends object> = Omit<T, MethodKeys<T>>;
function typeTest(): EntityFields<SomeClass> {
return null as any;
}
const theType = typeOf<typeof typeTest>();
console.log(theType.kind === ReflectionKind.function && theType.return);
// output yields subtypes fieldA, fieldB, fieldC, and someFunctionC
// the TS type does NOT include someFunctionC
Output:
$ ts-node index.ts
<ref *1> {
kind: 30,
typeName: 'EntityFields',
typeArguments: [
{
kind: 20,
classType: [Function],
types: [Array],
typeArguments: undefined
}
],
types: [
{
kind: 32,
name: 'fieldA',
type: [Object],
optional: undefined,
parent: [Object]
},
{
kind: 32,
name: 'fieldB',
type: [Object],
optional: undefined,
parent: [Object]
},
{
kind: 32,
name: 'fieldC',
type: [Object],
optional: undefined,
parent: [Object]
},
{
kind: 32,
name: 'someFunctionC',
type: [Object],
optional: undefined,
parent: [Object]
}
],
originTypes: [
{ typeName: 'Omit', typeArguments: [Array] },
{ typeName: 'Pick', typeArguments: [Array] }
],
parent: {
kind: 17,
name: 'typeTest',
return: [Circular *1],
parameters: [],
function: [Function: typeTest] { __type: [Array] }
}
}
Unfortunately, reference to this is not implemented at all in our type compiler, so referring to it breaks stuff in unexpected ways. I've added now a workaround that keyof this is handled as any (instead of never), so that your code should work. Please test and let me know! Thanks