TypeScript中带递归回调的泛型函数映射类型定义问题
问题场景与需求
我正在开发一个支持定义和触发「action」的工具包。Action是一类回调函数,接收payload参数,还能递归触发更多action。理想的使用方式如下:
import { ActionDef, getTrigger } from 'thePackage'; const action1 = ((payload, trigger) => { console.log('action1', payload) trigger('action2', {y: 'abc'}) }) satisfies ActionDef<MyActions, {x: number}>; const action2 = ((payload, trigger) => { console.log('action2', payload) trigger('action1', {x: 123}) }) satisfies ActionDef<MyActions, {y: string}>; const actions = { action1, action2 } type MyActions = typeof actions; const trigger = getTrigger(actions); function triggerSomeActions() { trigger('action1', {x: 123}); trigger('action1', {x: 234}); trigger('action2', {y: 'abc'}); }
我需要TypeScript能验证所有trigger调用的有效性:
- 包括
getTrigger返回的trigger函数 - 包括action内部回调的trigger函数
验证内容为:传入的action名称合法,对应payload类型匹配。
但当前实现因MyActions的循环类型引用无法正常工作,我需要一种既能正确实现类型校验,又不会给工具包使用者增加过多负担的方案。
当前包内类型定义
type ActionDef<A extends Actions, P> = (payload: P, triggerCallback: TriggerFunc<A>) => void type Actions = Record<string, ActionDef<any, any>>; type PayloadFromDef<D> = D extends ActionDef<any, infer P> ? P : never type TriggerFunc<A extends Actions> = (<K extends keyof A>(actionName: K, payload: PayloadFromDef<A[K]>) => void); declare function getTrigger<A extends Actions>(actions: A): TriggerFunc<A>;
现有方案的不足
有一种可行方案是单独定义action名称与payload的映射类型:
type ActionTypes = { action1: {x: number}; action2: {y: string}; }
再用该类型替代MyActions,但这种方式需要开发者额外维护一份类型定义,会损害开发者体验(DevX)。
内容的提问来源于stack exchange,提问作者simlmx
相关产品推荐
相关产品推荐

