0

I have a trouble with Typescript I am trying to infer the properties of an Object dynamically.

take a look at the below code

const Actions = {
    globalUI: {
        openModal: 'openModal'
    }
}

type Param = keyof typeof Actions;
type T = <T, K extends keyof T>(action: T, key: K) => T[K];
const fn = (param: Param) => {

    const action = mapper(Actions, param);

    return action
}
const mapper:T = (action, name) => {
    return action[name]
}

const action = fn('globalUI');

enter image description here

as you can see Typescript can infer a global UI properties

but When I put the additional property in the Actions Object enter image description here

Typescript doesn't infer Object properties

const Actions = {
    globalUI: {
        openModal: 'openModal'
    },
    LP: {
        addDirectory: 'addDirectory'
    }
}

type Param = keyof typeof Actions;
type T = <T, K extends keyof T>(action: T, key: K) => T[K];
const fn = (param: Param) => {

    const action = mapper(Actions, param);

    return action
}
const mapper:T = (action, name) => {
    return action[name]
}

const action = fn('globalUI');

enter image description here

How can I achieve it? please give any idea

1 Answer 1

1

Your mapper function works as expected :

type T = <T, K extends keyof T>(action: T, key: K) => T[K];

const mapper:T = (action, name) => {
    return action[name]
}

const action = mapper(Actions, 'globalUI');

action.openModel // works greak 

The problem lies in the fn function which infers a union as a return type. { openModal: string } | { addDirectory: string } in your example.

So you need to explicit the return type with a generic :

const fn = <S extends Param>(param: S): typeof Actions[S]  => {
    const action = mapper(Actions, param);
    return action
}

const action = fn('globalUI'); 

action.globalUI; // Ok now

Playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.