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
相关产品推荐
相关产品推荐

