Search code examples
typescriptgenericstype-inferencemapped-types

Typescript: infer the type of an Object key from another key in the same Object


Let's say I have an API like this:

function changePot(args: {newSize: number, newSoil: string}){

}
function water(args: { quantity: number, useIntrants: boolean}){

}
const API = {
    changePot,
    water
}

Now I would like to have a function that takes an array of actions to apply to my plants, and infers the type of the params depending on the name of the action passed, like this:

schedule([
 {id: 'rose1', action: 'water', params: {quatity: 1, useIntrants: false}},
 {id: 'baobab1', action: 'changePot', params: {newSize: 10, newSoil: 'mold'}},
 {id: 'cactus1', action: 'changePot', params: {newSize: 3, newSoil: 'sand'}},
])

But I can't find a way to do that, here is an attempt:

function schedule(args: {
    id: string;
    action: keyof typeof API,
    // Here I would need to reference the action passed above somehow
    params: Parameters<typeof API[action][0]>
}[]){

Here is a link to the typescript playground with the example above.

Any idea ?

Edit

Updated playground with @Dimava's answer!


Solution

  • Map your API to arg types and use that

    // {action: "changePot", ...} | {action: "water", ...} | ...
    type arg = {[K in keyof typeof API]: {
        id: string,
        action: K,
        params: Parameters<typeof API[K]>[0]
    }}[keyof typeof API]
    
    function shedule1(args: arg[]){}