最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typescript - How to get correct value type from generic object by key? - Stack Overflow

programmeradmin1浏览0评论

In the example I want to create a simple mapper which has to convert object values depends on its keys. But compiler throws an error:

Property 'a' does not exist on type 'TState[Key]'

I guess that TState[Key] means "some value of the object", but can't imagine how to change my code to make it work.

interface IListState {
    name: string;
    age: number;
    isValid: boolean;
    obj: {
        a: number;
    }
}


type TChangeMapper = <
    TState extends IListState = IListState,
    Key extends keyof TState = keyof TState,
>(
    key: Key,
    value: TState[Key]
) => unknown;

const mapper: TChangeMapper = (key, value) => {
    if (key === 'obj') {
        return value.a; // Property 'a' does not exist on type 'TState[Key]'
    }
};

const result = mapper('obj', { a: 123 });

In the example I want to create a simple mapper which has to convert object values depends on its keys. But compiler throws an error:

Property 'a' does not exist on type 'TState[Key]'

I guess that TState[Key] means "some value of the object", but can't imagine how to change my code to make it work.

interface IListState {
    name: string;
    age: number;
    isValid: boolean;
    obj: {
        a: number;
    }
}


type TChangeMapper = <
    TState extends IListState = IListState,
    Key extends keyof TState = keyof TState,
>(
    key: Key,
    value: TState[Key]
) => unknown;

const mapper: TChangeMapper = (key, value) => {
    if (key === 'obj') {
        return value.a; // Property 'a' does not exist on type 'TState[Key]'
    }
};

const result = mapper('obj', { a: 123 });
Share Improve this question edited Mar 13 at 14:36 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 13 at 14:32 BeardlessBeardless 253 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Evaluation on generic parameters is deferred, so to get an exact types in the function body you could avoid generic params and use a mapped type for the arguments with established key/value pairs:

Playground

type Args = {[K in keyof IListState]: [key: K , value: IListState[K]]}[keyof IListState];
type TChangeMapper = (...args: Args) => unknown;

const mapper: TChangeMapper = (key, value) => {
    if (key === 'obj') {
        return value.a;
    }
    return null;
};
发布评论

评论列表(0)

  1. 暂无评论