I've been working on creating a versatile function that takes an object T and a string property name of that object T.
To guide me, I referred to https://www.typescriptlang.org/docs/handbook/advanced-types.html under the section: Distributive conditional types.
I managed to come up with a solution that functions without generics. However, when I attempt to switch the explicit types to a generic type, TypeScript fails to compile.
Here is the non-generic version that currently works:
export type TypedPropertyNames<T, P> = { [K in keyof T]: T[K] extends P ? K : never }[keyof T];
export type StringPropertyNames<T> = TypedPropertyNames<T, string>;
interface Test {
test: string;
}
function non_generic(form: Test, field: StringPropertyNames<Test>): string {
return form[field];
}
This implementation works flawlessly.
However, as soon as I transform the Test interface into a generic argument, the compilation fails.
export type TypedPropertyNames<T, P> = { [K in keyof T]: T[K] extends P ? K : never }[keyof T];
export type StringPropertyNames<T> = TypedPropertyNames<T, string>;
function generic<T>(form: T, field: StringPropertyNames<T>): string {
return form[field]; // This causes a compile error
}
Is this behavior expected or could it potentially be a TypeScript bug? Any guidance on how to make the generic version work smoothly (without any workarounds) would be greatly appreciated.
Update 1:
Compilation error logged:
Type 'T[{ [K in keyof T]: T[K] extends string ? K : never; }[keyof T]]' is not assignable to type 'string'.
Refer to this Playground link