My code includes a dispatch function that takes a parameter and then returns a different function based on the parameter value. Here is a simplified version:
type Choice = 'start' | 'end';
function dispatch(choice: Choice) {
switch(choice) {
case 'start':
return startProcess;
case 'end':
return endProcess;
}
}
function startProcess(name: string) {
console.log(name);
}
function endProcess(code: number) {
console.log(code);
}
Initially, everything worked fine because all returned functions had the same signature. However, adding another function with a different signature caused an issue. The problem lies in TypeScript not being able to infer the correct type of the returned function from the 'dispatch' function.
Now, the following usage is no longer possible due to TypeScript's inability to understand the return type:
dispatch('start')('123'); // Argument of type 'string' is not assignable to parameter of type 'never'.
dispatch('end')(123); // Argument of type 'number' is not assignable to parameter of type 'never'.
Is there a way to resolve this issue or perhaps implement a more robust dispatch function that doesn't face such difficulties?
Here's a link to a playground.
Edit
I have found a partial solution using generics. This allows me to correctly call the dispatched function, but I encounter additional errors within the dispatch function which I am struggling to comprehend.
type Choice = 'start' | 'end';
type DispatchedFunction<T extends Choice> = T extends 'start' ? typeof startProcess : typeof endProcess;
function dispatch<R extends Choice>(choice: R): DispatchedFunction<R> {
switch(choice) {
case 'start':
// Type '(name: string) => void' is not assignable to type 'DispatchedFunction<R>'.
return startProcess;
case 'end':
// Type '(code: number) => void' is not assignable to type 'DispatchedFunction<R>'.
return endProcess;
}
return () => {} // Added to prevent function from returning undefined
}