You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript高阶函数中基于对象键自动推导Action类型的问题

TypeScript 高阶函数Action类型自动收窄实现问题

我正在尝试创建一个接收函数对象的高阶函数,遵循以下规则:

  • 对象中的每个函数都接收state与action两个参数
  • action对象包含必填字段type,payload为可选字段
  • 函数对象的键名必须与对应处理的action的type字段值完全匹配

首先定义的基础类型如下:

type RequiredActionFields<P = {}> = {
  type: string;
  payload: P;
};

当前实现代码

type SomeFunction<S, A> = (state: S, action: A) => void;

type ObjWithFunctions<S, A extends RequiredActionFields> = Record<
  A["type"],
  SomeFunction<S, A>
>;

const functionThatDoesThings = <S>(state: S, cb: (draft: S) => void) => {
  // 其他内部逻辑
  return state;
};

function createThing<S, A extends RequiredActionFields>(
  functions: ObjWithFunctions<S, A>
) {
  return (state: S, action: A) => {
    const reducer = functions[action.type as keyof typeof functions];

    if (!reducer) {
      throw new Error(`Unhandled action type`);
    }

    const nextState = functionThatDoesThings(state, (draft) => {
      reducer(draft, action);
    });

    return nextState;
  };
}

期望调用效果

我希望按照如下方式调用函数时,每个键对应的处理函数能自动推导匹配的action子类型,无需手动写类型守卫收窄:

type Action =
  | { type: "something"; payload: { id: 1 } }
  | { type: "another"; payload: { close: true } };

type State = {
  entities: [];
  open: boolean;
};

createThing<State, Action>({
  something: (state, action) => {
    // 当前此处报类型错误,期望根据对象键名'something'自动推导action类型,直接访问payload.id无报错
    action.payload.id;

    if (action.type === "something") {
      // 手动判断type收窄类型后可以正常工作
      action.payload.id;
    }
  },
  another: (state, action) => {
    // 当前此处同样报类型错误,期望自动推导为对应type为"another"的action分支
    action.payload.close;
  }
});

核心问题

需要调整类型定义,实现类型自动收窄:函数对象中对应键名的处理函数,其action参数类型自动匹配对应type值的action分支类型,不需要手动通过action.type === xxx的类型守卫做收窄。


内容的提问来源于stack exchange,提问作者Marco Ripamonti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 00:16:12