Reputation: 1267
Let's say I have an object of factories like this one:
const factories = {
foo: () => 'some string',
bar: () => 123,
};
I would like to use this object to type a class property. The goal for this class is to have a property with the same keys than above, but with the return type of the factories instead of the factories themselves:
class MyClass {
myItems: ???; // What type here to have the below working?
}
const instance = new MyClass();
instance.myItems.foo; // Should be a string, not a function
instance.myItems.bar; // Should be a number, not a function
In short, I don't want that:
class MyClass {
myItems: typeof factories;
}
But something like the below:
class MyClass {
myItems: Record<keyof typeof factories, ReturnType<typeof factories>>;
}
But of course, the above does not work, with this error:
TS2344: Type '{ foo: () => string; bar: () => number; }' does not satisfy the constraint '(...args: any) => any'. Type '{ foo: () => string; bar: () => number; }' provides no match for the signature '(...args: any): any'.
Do you have any help with that?
Thanks in advance!
Upvotes: 0
Views: 41
Reputation: 8295
Here's a way you could do it:
const factories = {
foo: () => 'some string',
bar: () => 123,
};
type Factory<T> = () => T;
type FactoryValues<T> = {
[K in keyof T]: T[K] extends Factory<infer U> ? U : never;
};
const values: FactoryValues<typeof factories> = {
foo: 'test',
bar: 123,
};
Upvotes: 1