declare class GenericClass<T, U = T> {
constructor(value: T);
u: U;
}
function takesRecordOfGenericClass<
R extends Record<string, GenericClass<any, any>>
>(r: R): R {
return r;
}
const genericClass = new GenericClass(1);
// ^ NumberField<number, number>
const record = {
property1: new GenericClass(1)
// ^ NumberField<number, number>
}
const widenedInference = takesRecordOfGenericClass({
property1: new GenericClass(1)
// ^ NumberField<number, any>
// How do I get this to infer as `NumberField<number, number>` like it normally does?
});
I feel the code speaks more clearly than I can. It seems that when inferring for R extends Record<string, GenericClass<any, any>> it ends up widening the inner properties. This does NOT happen with just a single field, e.g. in a similar function with T extends GenericClass<any, any> the inference is always exact. For some reason though Record<string, GenericClass<any, any>> ends up widening each value.
This does NOT happen with R extends any, R extends object, R extends Record<string, unknown> or anything else I can throw at it. It still happens during subclassing.
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.