如何在TypeScript中为dispatch函数正确添加类型并通过类型检查?
问题分析与解决方案
原代码的问题在于,泛型Arg被定义为所有函数参数的联合类型,当你通过arg.type获取对应的函数h时,TypeScript无法推断出arg和h的参数类型是严格匹配的——h此时是所有函数的联合类型,而联合类型的函数调用要求参数必须满足所有函数参数的交集,显然{type: 'a'}和{type: 'b'}没有交集,因此类型检查失败。
要解决这个问题,我们需要让泛型绑定到hh的键类型上,确保参数arg和对应的函数h类型严格对应:
const hh = { a: (_: { type: 'a' }) => '', b: (_: { type: 'b' }) => '', } as const; export function dispatch<K extends keyof typeof hh>( arg: Parameters<typeof hh[K]>[0] ) { const h = hh[arg.type]; h(arg); // 现在类型检查通过 }
原理说明
- 泛型
K约束为keyof typeof hh,也就是'a' | 'b'; arg的类型被定义为hh[K]这个函数的第一个参数,这意味着当K是'a'时,arg必须是{type: 'a'},当K是'b'时,arg必须是{type: 'b'};- 此时
hh[arg.type]会被TypeScript推断为hh[K],和arg的类型完全匹配,因此调用h(arg)不会有类型错误。
你还可以进一步优化类型定义,提前提取参数类型,让代码更清晰:
const hh = { a: (_: { type: 'a' }) => '', b: (_: { type: 'b' }) => '', } as const; type HandlerKeys = keyof typeof hh; type HandlerArg<K extends HandlerKeys> = Parameters<typeof hh[K]>[0]; export function dispatch<K extends HandlerKeys>(arg: HandlerArg<K>) { const h = hh[arg.type]; h(arg); }
这样无论后续hh新增多少键值对,dispatch函数的类型都能自动适配,无需手动修改。
内容的提问来源于stack exchange,提问作者Jozef Mokry
相关产品推荐
相关产品推荐

