TypeScript获取组合类方法参数类型及Worker调用类型问题
解决TypeScript Worker线程方法调用的类型错误与参数推断问题
首先修正类型定义中的笔误:IWorker里的serviceSomethingElse对应的类型应为IServiceSomethingElse,而非IServiceColorPicker,否则类型会不匹配:
type IWorker = { serviceTask: IServiceTask, serviceSomethingElse: IServiceSomethingElse } type IServiceTask = { doSomething: (arg1: number) => Promise<void>; } type IServiceSomethingElse = { doSomething1: (params: Record<string, any>) => Promise<string>; }
问题1:消除"call doesn't exist on type IWorker[T][K]"错误
错误根源是TypeScript无法确定IWorker[T][K]是函数类型,需要通过泛型约束或类型断言明确这一点,同时注意参数引用的正确性(原代码中未通过parameters对象访问传入的参数)。
方案1:泛型约束限定函数属性键
通过条件类型约束K只能是服务对象中函数类型的属性键,让TypeScript明确知道IWorker[T][K]是函数:
const runInWorker = < T extends keyof IWorker, // 仅保留服务中值为函数类型的键 K extends { [Key in keyof IWorker[T]]: IWorker[T][Key] extends Function ? Key : never }[keyof IWorker[T]] >(parameters: { workerService: T, serviceMethod: K, methodParams: Parameters<IWorker[T][K]>[0] }) => { const worker: IWorker = new Worker(); // 此时TS已识别为函数,可直接调用call worker[parameters.workerService][parameters.serviceMethod].call(this, parameters.methodParams); // 后续逻辑... }
方案2:类型断言快速修复
如果不想修改泛型约束,可在调用时将属性断言为函数类型:
const runInWorker = < T extends keyof IWorker, K extends keyof IWorker[T], P = Parameters<Extract<IWorker[T][K], (...args: any[]) => any>>[0] >(parameters: { workerService: T, serviceMethod: K, methodParams: P }) => { const worker: IWorker = new Worker(); const targetMethod = worker[parameters.workerService][parameters.serviceMethod] as (...args: any[]) => any; targetMethod.call(this, parameters.methodParams); // 后续逻辑... }
问题2:正确推断方法的参数类型
核心是确保Parameters泛型的输入是函数类型,结合泛型约束或Extract工具类型提取函数类型后,即可自动推断参数:
自动推断实现
在泛型中通过Parameters<IWorker[T][K]>[0]直接获取函数的第一个参数类型(因为你的方法都是单参数设计),当传入workerService和serviceMethod时,methodParams会自动匹配对应类型:
- 传入
serviceTask+doSomething:methodParams必须为number类型 - 传入
serviceSomethingElse+doSomething1:methodParams必须为Record<string, any>类型
调用示例
// 正确调用:参数类型自动推断为number runInWorker({ workerService: 'serviceTask', serviceMethod: 'doSomething', methodParams: 123 }); // 正确调用:参数类型自动推断为Record<string, any> runInWorker({ workerService: 'serviceSomethingElse', serviceMethod: 'doSomething1', methodParams: { name: 'test' } }); // 错误调用:TS会报错,参数类型不匹配 runInWorker({ workerService: 'serviceTask', serviceMethod: 'doSomething', methodParams: { name: 'test' } });
为什么之前的Parameters无法使用?
原代码未对IWorker[T][K]做函数类型约束,TypeScript无法确认它符合Parameters的输入要求(Parameters仅接受函数类型)。通过泛型约束限定K为函数属性键,或用Extract<IWorker[T][K], (...args: any[]) => any>提取函数类型后,Parameters即可正常解析。
内容的提问来源于stack exchange,提问作者goldcvt
相关产品推荐
相关产品推荐

