简体   繁体   English

Typescript map object 类型到强类型数组

[英]Typescript map object type to strongly typed array

I have an object type which I want to map to a strongly typed key, value array.我有一个 object 类型,我想将 map 转换为强类型键值数组。

This is what I came up with so far:到目前为止,这是我想出的:

export interface StepWidgetItem<T, V> {
    key: T;
    value: V;
}

interface UseStepWidgetsContainer<T extends object> {
    data: T;
}

interface UseStepWidgetsContainerProps<T extends object> {
    items: StepWidgetItem<keyof T, T[keyof T]>[];
}

export const useStepWidgetsContainer = <T extends object>({
    items,
}: UseStepWidgetsContainerProps<T>): UseStepWidgetsContainer<T> => {
    const data = {} as T;

    console.log(items);

    return {
        data,
    };
};

The problem i when I call it like this:当我这样称呼它时的问题是:

interface Data {
    test: string;
    test2: number;
}

useStepWidgetsContainer<Data>({
    items: [
        {
            key: 'test',
            value: 'test',
        },
        {
            key: 'test2',
            value: 'test', // should be an error, but string is currently allowed...
        },
        {
            key: 'test2',
            value: 1,
        },
    ],
});

The value of array item with key: 'test2' must be a number, but currently it may be any type of the values of Data, so string|number . key: 'test2' 的数组项的值必须是一个数字,但目前它可以是任何类型的数据值,所以string|number

Is it possible to force a number when key === 'test2'?当 key === 'test2' 时是否可以强制输入一个数字?

You are very close The problem is that StepWidgetItem<keyof T, T[keyof T]> will mix any key of T with any value in T .你非常接近问题是StepWidgetItem<keyof T, T[keyof T]>会将T的任何键与T中的任何值混合。

The solution is to first associate the key with the value creating a type for each property, for ex: StepWidgetItem<"test", string> StepWidgetItem<"test2", number> .解决方案是首先将键与值关联起来,为每个属性创建一个类型,例如: StepWidgetItem<"test", string> StepWidgetItem<"test2", number> We can do this using a mapped type to first create for each property, the associated StepWidgetItem and then index into the mapped type using [keyof T] to get a union of all StepWidgetItem types we just created.我们可以使用映射类型来执行此操作,首先为每个属性创建关联的StepWidgetItem ,然后使用[keyof T]索引映射类型以获得我们刚刚创建的所有 StepWidgetItem 类型的联合。

interface UseStepWidgetsContainerProps<T extends object> {
    items: Array<{
      [P in keyof T]: StepWidgetItem<P, T[P]>
    }[keyof T]>
}

Playground Link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM