DEV Community

tmhao2005
tmhao2005

Posted on

Interesting TypeScript issue

I recently ran into the issue as following:

const actions = { call: (num: number) => { // todo }, speak: (text: string) => { // todo }, } // I'm going to create a function which can pass the action  // and its corresponding argument as following: doThings('call', 911); doThings('speak', 'hello'); // so here the simple implemenatation type Actions = typeof actions; function doThings<T extends keyof Actions>(p0: T, ...[p1]: Parameters<Actions[T]>) { const action = actions[p0]; // error! // Argument of type 'string | number' is not assignable to parameter of type 'never'. action(p1); } 
Enter fullscreen mode Exit fullscreen mode

As we can see, it has a typing issue as the comment. I quickly searched for solution, then I ended up following up this issue which was open long ago https://github.com/microsoft/TypeScript/issues/30581.

Looks like we haven't yet had a good solution for the issue though. I eventually came up with a solution after reading a few solutions/hackarounds from comments as following:

// create arguments map type ArgsMap = { call: [num: number, message: string]; speak: [message: string]; }; // this is a key where we have to define the type for the object const actions: {[K in keyof ArgsMap]: (...p: ArgsMap[K]) => void} = { call: (num, message) => { // todo }, speak: (text) => { // todo }, } // eventually the function signature  function getAcion<K extends keyof ArgsMap>(name: K, ...p: ArgsMap[K]) { const action = actions[name] // works! action(...p) } 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)