Reputation: 1821
I would like to infer the type of a parameter in Typescript but was not lucky until yet.
I have the following Code
// is it possible to find out the type of the payload parameter?
type Dispatch<T> = (prop: keyof T, payload?: any) => any;
class TestClass<T> {
obj: T;
dispatch: Dispatch<T> = (prop, payload) => {
const func = this.obj[prop];
return (func as any)(payload);
};
constructor(obj: T) {
this.obj = obj;
}
}
interface SomeFuncs {
foo(payload: string): string;
bar(payload: number): string;
}
const someFuncs: SomeFuncs = {
foo(payload) {
return 'Hello ' + payload;
},
bar(payload) {
const result = 10 + payload;
return 'Your result is ' + result;
},
};
const testClass = new TestClass(someFuncs);
const result = testClass.dispatch('bar', 'bla'); // I would like to get here an error because the payload for bar should be of type number
console.log(result);
Is it somehow possible to infer the type for payload in the Dispatch<T>
type? I played around with the Parameters
stuff which was added in 2.8 but still have no clue how to solve it.
The key on the other hand works just fine. So since i have the Base Type T
and the key i thought it should be possible to find out the type of the parameter.
Upvotes: 2
Views: 103
Reputation: 249546
Dispatch
would have to be a generic function (not just a generic type) to be able to capture the actual type of the argument passed in and use this to get the corect parameters from T
// is it possible to find out the type of the payload parameter
type Dispatch<T extends Record<keyof T, (...a: any[]) => any>> = <K extends keyof T>(prop: K, ...payload: Parameters<T[K]>) => any;
class TestClass<T extends Record<keyof T, (...a: any[]) => any>> {
obj: T;
dispatch: Dispatch<T> = (prop, ...payload) => {
const func = this.obj[prop];
return func(...payload);
};
constructor(obj: T) {
this.obj = obj;
}
}
interface SomeFuncs {
foo(payload: string): string;
bar(payload: number): string;
}
const someFuncs: SomeFuncs = {
foo(payload) {
return 'Hello ' + payload;
},
bar(payload) {
const result = 10 + payload;
return 'Your result is ' + result;
},
};
const testClass = new TestClass(someFuncs);
const result = testClass.dispatch('bar', 'bla'); // err
const result2 = testClass.dispatch('bar', 0); // ok
console.log(result);
Note: solution is Typescript 3.0 and above
Upvotes: 3