gpt4 book ai didi

typescript - 无法键入每个键映射到通用值的对象

转载 作者:行者123 更新时间:2023-12-03 20:39:01 25 4
gpt4 key购买 nike

我在键入一个对象时遇到了一些问题,其中每个键都映射到一个通用值。
我已将我的代码简化为这个最小的可重现示例:

export type Action<T extends string, P> = {
type: T;
error: false;
payload: P;
};

type Event = { action: string; [trait: string]: string; };

type Handlers = {
[key: string]: <T extends string, P>(action: Action<T, P>) => Event;
};

export type ActionAType = Action<
"ACTION_A",
{ id: number; a: string; }
>;


export type ActionBType = Action<
"ACTION_B",
{ id: number; b: string }
>;

const HANDLERS: Handlers = {
"QUERY_GROUP_START": (action: ActionAType) => {
return { action: "START", a: action.payload.a };
},

"QUERY_GROUP_CONTINUE": (action: ActionBType) => {
return { action: "CONTINUE", id: action.payload.id };
}
};
我有一个 Action 泛型类型和该泛型类型的一些实例( ActionAActionB ),我希望我的 Handlers 类型对应一个对象,其中每个元素都是一个通用键值对。
我得到的错误是:
Type '(action: ActionAType) => { action: string; a: string; }' is not assignable to type '<T extends string, P>(action: Action<T, P>) => Event'.
Types of parameters 'action' and 'action' are incompatible.
Type 'Action<T, P>' is not assignable to type 'ActionAType'.
Types of property 'type' are incompatible.
Type 'T' is not assignable to type '"ACTION_A"'.
Type 'string' is not assignable to type '"ACTION_A"'.(2322)
我需要这种模式的原因是我在 Redux 中间件中有一组 Action 处理程序。 middleware 函数是这样工作的:
  • 它接收一个 Action (类型是 Action )
  • 调用该操作的处理程序

  • 这个中间件在一个库中,所以它没有处理程序列表。相反,库的客户端在配置中间件时传入处理程序列表。
    export const coreAnalytics = (
    customHandlers: Handlers
    ) => () => (next: (action: Action) => void) => (action: Action) => {
    const customHandler: (action: Action) => Event =
    customHandlers[action.type];

    if (customHandler) {
    const analyticsEvent: Event = customHandler(action);

    ...
    }

    ...
    };
    请注意,这里没有 Action 的联合类型。如果我们有这个,那么将其重写为一个打开 Action 类型并处理每个 Action 的函数将非常简单。
    我在这里有一个游乐场链接:
    https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBDAnmYcCCBjGBLCA7AHgBU5QZg8ATAZzmpimzwHMAaOABQD44BeOAN4BYAFBxxCZMABccIgG5RE0lCjRZAMwCGAG2rBFYiWC2IdELZVkdDAX0OikKOAAktVHcCi1+wo+IBtAGtgRFl6RhYAXVliUhByKloIpjZOLgAKLSxcPFlMHHxidm4ASj4eACMICE93OwcRUEhYSWcC3LQiKT50HKKlCQAiNABhIgBJAHkAOQB9NCHWQfEBOGwrODwAVwBbSq95OC1whlSj21EuRtFm6HgnVA78ACFu535nwhW4EfHp+YvJY-NYbWQ7faHOCVU6RZhwS4ia6iUQYfD0VxoGYAEQAMgBRABKAGVZG4PF4fIIfkMAIoAVSJAE05gBxQlTekcObEohoQlEIayLL9PJ9Qp4LpScq8Hh+ZTKKDAGDbKB4BBQbYGH62ZYiGkM5lsjlcuajWaTGaMoVwEUS-Kit7SirU-wKpUqtVwbR6bVuxH2IA

    最佳答案

    可以这样想:在 Handlers 类型的对象中,调用一个函数属性时的唯一保证是它的 action 参数将是一个 Action<T, P>T 可以是任何 stringP 可以是任何东西。这使得在将属性分配给 Handlers 对象时要求任何更具体的保证是错误的。在您的两种情况下,您要求 action 专门为 ActionATypeActionBType ,这意味着您要求 T 专门为 'ACTION_A''ACTION_B' ,而 P 专门为 { id: number; a: string; }{ id: number; b: string } 。这对于 Handlers 的输入方式来说太具体了。
    我同意 Federkun 的观点,即最好的方法是不要明确输入 HANDLERS 。 (实际上,您可能根本不需要 Handlers ,甚至不需要作为别名。)如果没有显式类型,对象上的每个属性都有自己的窄类型,并提供有关 TP 的相关保证。
    如果您的完整代码有某种原因需要在 HANDLERS 上进行显式输入,那么您可能需要更新/扩展您的示例以反射(reflect)这一点。

    关于typescript - 无法键入每个键映射到通用值的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67765647/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com