Nisha Patel
Problem
I have an object that looks something like this:
And I have a generic type that looks like this:
The use case for this generic type works like this:
As you can see, it extracts the type of the action.payload parameter from the actions.foo() function.
I want to have a generic type that would allow me to do the same thing but for the entire actions object.
What have I tried?
I tried creating a generic type that looks like this:
but it doesn't exactly do what I was expecting:
Instead of only extracting the parameter type from actions.foo() it extracts it from every function and creates a type union. What I want is for the type of mappedActions.foo() to be (payload: string) => void.
Here is the playground I was using: >TypeScript Playground.
Solution
The reason you are getting union types is the Record<keyof A, ActionMapper<A[keyof A]>>: it creates an object with all the keys of A, with each property having the type of ActionMapper applied to all the values of A. What you want, however, is an object with all the keys of A, with each property having the type of ActionMapper applied to the value of that same key of A.
You can do this using a >mapped type:
This creates the wanted object, where the key used in the value for each property is the key for that property, and just that key.
The difference is that in a mapped type, you can base each value on the key for that property. With Record, all the values are the same.
Given:
Simplifying leaves the following:
Here, keyof T is all the property keys of T, and T[keyof T] is all the property values of T. The two keyof expressions are not linked.
We can simplify the mapped type too:
And now we can compare the Record-based type with the custom mapped type. You can easily see the difference:
Suggested blogs:
>Why Typescript does not allow a union type in an array?
>Narrow SomeType vs SomeType[]
>Create a function that convert a dynamic Json to a formula in Typescript
>How to destroy a custom object within the use Effect hook in TypeScript?
>How to type the values of an object into a spreadsheet in TypeScript?
>Type key of record in a self-referential manner in TypeScript?
>How to get the last cell with data for a given column in TypeScript?
>Ignore requests by interceptors based on request content in TypeScript?
>Create data with Typescript Sequelize model without passing in an id?
>How to delete duplicate names from Array in Typescript?