为含函数对象的容器创建包装函数的TypeScript类型错误排查
解决方法
核心问题是TypeScript无法在函数内部自动关联泛型参数T、U与post${U}方法的类型关系,需要通过类型断言或辅助类型定义帮编译器理清类型关联。
方案1:类型断言快速修复
直接对调用的方法进行类型断言,明确它符合参数和返回值的类型要求:
class APIContainer { api1!: API1; api2!: API2; } class API1 { postA(x: string): string { return '' } postB(x: number): number { return 1 } patchA(x: string): string { return '' } } class API2 { postX(x: string): string { return '' } postY(x: number): number { return 1 } patchX(x: string): string { return '' } } type ExtractPostMethods<T> = T extends `post${infer V}` ? V : never; function doCall<T extends keyof APIContainer, U extends ExtractPostMethods<keyof APIContainer[T]>>( api: T, entity: U, data: Parameters<APIContainer[T][`post${U}`]>[0] ): ReturnType<APIContainer[T][`post${U}`]> { const container = new APIContainer(); // 断言方法类型,让编译器确认这是符合要求的函数 const method = container[api][`post${entity}`] as (data: Parameters<APIContainer[T][`post${U}`]>[0]) => ReturnType<APIContainer[T][`post${U}`]>; return method(data); } const result = doCall('api1', 'A', '1'); result.length; // 类型推断正常,返回string
方案2:重构辅助类型增强类型关联
通过定义映射类型,提前梳理API容器的post方法结构,让TypeScript更清晰地跟踪类型:
class APIContainer { api1!: API1; api2!: API2; } class API1 { postA(x: string): string { return '' } postB(x: number): number { return 1 } patchA(x: string): string { return '' } } class API2 { postX(x: string): string { return '' } postY(x: number): number { return 1 } patchX(x: string): string { return '' } } // 定义所有可用的post方法映射:{ [API键]: { [方法后缀]: (参数) => 返回值 } } type APIPostMethods = { [K in keyof APIContainer]: { [M in ExtractPostMethods<keyof APIContainer[K]>]: APIContainer[K][`post${M}`] } }; function doCall<K extends keyof APIPostMethods, M extends keyof APIPostMethods[K]>( api: K, entity: M, data: Parameters<APIPostMethods[K][M]>[0] ): ReturnType<APIPostMethods[K][M]> { const container = new APIContainer(); return container[api][`post${entity as string}`](data); } const result = doCall('api1', 'A', '1'); result.length; // 类型推断正常
原代码报错原因
泛型参数T和U在外部调用时能正确推断,但函数内部编译器无法确认container[api][post${entity}]的类型与Parameters/ReturnType定义的类型完全匹配——模板字符串类型的拼接在泛型上下文中无法被编译器自动关联,因此需要手动辅助类型关联或断言。
内容的提问来源于stack exchange,提问作者Bart van den Burg
相关产品推荐
相关产品推荐

