TypeScript中myFunction返回类型异常,参数类型提取不符合预期
解决TypeScript中action函数的参数类型约束问题
你当前的代码无法正确约束action函数的参数,核心问题是遍历联合类型的type时,没有针对每个type提取对应的payload结构,导致所有action的参数都是所有payload类型的交集,无法区分不同action的参数要求。
以下是修正后的完整代码:
// 辅助类型:从payload联合类型中提取指定type对应的结构 type ExtractActionPayload<Payload extends { type: string }, T extends Payload['type']> = Extract<Payload, { type: T }> // 重新定义Base类型,更精准描述reducer结构 type Base = { [key: string]: <S>(state: S, payload: { type: string } & Record<string, any>) => S } const myFunction = <T extends Base>(arg: T) => { return { actions: {} as { [Domain in keyof T]: { [ActionType in Parameters<T[Domain]>[1]['type']]: // 提取当前actionType对应的payload结构 ExtractActionPayload<Parameters<T[Domain]>[1], ActionType> extends infer P ? // 移除type字段后,剩余属性为空则无需参数,否则传入对应属性 Omit<P, 'type'> extends {} ? () => void : (payload: Omit<P, 'type'>) => void : never } } } } // 测试代码 const reducer1 = (state: boolean, payload: { type: 'foo', payload: number } | { type: 'batman' }) => state const reducer2 = (state: string, payload: { type: 'bar' }) => state const { actions } = myFunction({ domain1: reducer1, domain2: reducer2 }) // 验证预期行为: actions.domain1.batman() // ✅ 无需参数 actions.domain1.foo({ payload: 123 }) // ✅ 需要传入number类型的payload // actions.domain1.foo() ❌ 报错,缺少必要参数 actions.domain2.bar() // ✅ 无需参数
关键逻辑说明
- ExtractActionPayload辅助类型:利用TypeScript内置的
Extract工具类型,从payload联合类型中筛选出与当前actionType匹配的结构,确保每个action对应正确的payload定义。 - 条件类型处理参数:通过
Omit<P, 'type'>移除固定的type字段后,判断剩余属性是否为空:- 为空则说明该action不需要额外参数,函数定义为
() => void; - 不为空则要求传入对应的payload属性,函数定义为接收该结构的参数。
- 为空则说明该action不需要额外参数,函数定义为
- 修正Base类型:将reducer定义为泛型函数,帮助TypeScript更精准地推断state和payload的类型,避免
any导致的类型信息丢失。
内容的提问来源于stack exchange,提问作者johann1301s
相关产品推荐
相关产品推荐

