TypeScript中const unions作为不同签名回调注册表的类型问题
解决TypeScript联合函数类型调用的类型错误
问题分析
你这段代码里,registry[type].magic(...magicArgs)报错是因为TypeScript将Registry[T]["magic"]解析成了联合类型((d: number) => number) | ((d: string) => string)。调用联合类型的函数时,TypeScript要求参数必须满足所有分支的参数类型,也就是number & string(即never),所以出现类型不匹配的错误。
修复方案
这里给出两种可行的修复方式:
方案1:类型断言
直接将registry[type].magic断言为对应泛型T的具体函数类型:
const registry = { foo: { magic: (d: number) => d }, bar: { magic: (d: string) => d } } as const type Registry = typeof registry const registryMagic = <T extends keyof Registry>(type: T, magicArgs: Parameters<Registry[T]["magic"]>) => { // 断言为对应T的具体函数类型 (registry[type].magic as (...args: Parameters<Registry[T]["magic"]>) => ReturnType<Registry[T]["magic"]>)(...magicArgs) } registryMagic("foo", [123]) registryMagic("bar", ["test"])
方案2:使用辅助函数关联类型
通过辅助函数强制TypeScript跟踪具体的类型分支,避免类型断言:
const registry = { foo: { magic: (d: number) => d }, bar: { magic: (d: string) => d } } as const type Registry = typeof registry const callMagic = <T extends keyof Registry>(entry: Registry[T], args: Parameters<Registry[T]["magic"]>) => { entry.magic(...args) } const registryMagic = <T extends keyof Registry>(type: T, magicArgs: Parameters<Registry[T]["magic"]>) => { callMagic(registry[type], magicArgs) } registryMagic("foo", [123]) registryMagic("bar", ["test"])
两种方式都能让TypeScript正确关联type参数和magicArgs的类型,消除错误。
内容的提问来源于stack exchange,提问作者lipp
相关产品推荐
相关产品推荐

