网站搜索

如何为我的上下文派发创建一个 TypeScript 类型,基于另一个接口的值?


我想为我的“reducer”函数创建一个类型。

我的函数“reducer”接收两个参数,第一个是当前状态,第二个是通过上下文分发发送过来的内容(用于使用 reducer)。

const reducer = (
    state: any,
    props: {
        action: string,
       value: any,
    } 
) => {
...
}

第二个参数将始终是一个具有两个属性的对象:action 和 value。

但是,我不喜欢属性“value”允许输入任何内容。这就是为什么我喜欢创建一个动态的“type”。

我有一个接口,包含我上下文的所有信息。

DefaultValueContextInterface interface {
    floatMsgError: string;
    isOpenSidebar: boolean;
    .....
}

我希望的是,这种我想要创建的新“类型”只允许,例如:

{
    action: "floatMsgError",
    value: string,
} 

为什么 “value” 只允许 “string”?因为在接口 “DefaultValueContextInterface” 中,属性 “floatMsgError” 的类型是 string。对于 “DefaultValueContextInterface” 接口中的每一个属性都是如此自动决定的。如果传递给函数 “reducer” 的 “action” 值等于 “isOpenSidebar”,那么 “value” 的值必须是 boolean 类型。

我可以手动创建这种类型,很简单:

{
    action: "floatMsgError",
    value: string,
} 
| {
    action: "isOpenSidebar",
    value: boolean,
}

但是,我在我的上下文中没有那两个属性。它们有很多。那样做并不理想。

我也尝试过使用“[P in keyof DefaultValueContextInterface]”,但是,我只能将它组合成这样:

type Props = {
    [P in keyof DefaultValueContextInterface]: {
        action: P;
        value: DefaultValueContextInterface[P];
    };
};

这对我不起作用。因为它生成了一个对象,而这不是我需要的。但内部对象确实接近我需要的。我只是不知道如何用另一种方式编写循环来使它起作用。

我目前有这个:

type Props = {
  action: keyof DefaultValueContextInterface;
  value: DefaultValueContextInterface[keyof DefaultValueContextInterface];
};

但是,这根本不会将“action”的值与“value”的值关联起来 :/

答案#1

你映射类型的方法几乎正确。你只需要通过使用 keyof DefaultValueContextInterface 索引类型来创建一个联合类型。

interface DefaultValueContextInterface {
    floatMsgError: string
    isOpenSidebar: boolean
}

type Props = {
    [P in keyof DefaultValueContextInterface]: {
        action: P
        value: DefaultValueContextInterface[P]
    }
}[keyof DefaultValueContextInterface]

操场