TypeScript中函数作为参数注入时的参数冲突问题问询
问题描述
我希望编写一个足够通用的函数,可接收任意informer和mapper并实现依赖注入,确保在informer和mapper变更时无需修改核心逻辑,但目前函数参数的泛化处理存在问题。若将myFunc的inform签名中的unknown改为any,会收到“any不建议使用”的警告。
接口定义
interface Document { name: string } interface Mapper { (doc: Document): unknown }
函数实现
const myFunc = async ( inform: (payload: unknown)=>Promise<Record<string, unknown>>, document: Document, mapper: Mapper): Promise<string> => { const response = <Record<string, unknown>> await inform(mapper(document)); return response })
问题场景
class APIClient { async inform(payload: RequestInfo): Promise<Record<string, unknown>> { // 实现代码 } } const apiClient = new APIClient(); const result = await myFunc( apiClient.inform, // 报错:unknown无法赋值给RequestInfo someData, someMapper );
解决方案
核心问题是当前类型定义未关联mapper的输出类型与inform的输入类型,导致类型不兼容。可以通过泛型实现类型安全的通用化,同时避免使用any:
重构后的接口与函数
interface Document { name: string } // 泛型Mapper,返回类型由泛型参数P指定 interface Mapper<P> { (doc: Document): P } // 泛型myFunc,用P关联inform的参数和mapper的返回类型 const myFunc = async <P>( inform: (payload: P) => Promise<Record<string, unknown>>, document: Document, mapper: Mapper<P> ): Promise<Record<string, unknown>> => { const response = await inform(mapper(document)); return response; };
适配问题场景
现在使用APIClient的inform时,只需让mapper返回RequestInfo类型,类型检查会自动通过:
class APIClient { async inform(payload: RequestInfo): Promise<Record<string, unknown>> { // 实现代码 return {}; } } const apiClient = new APIClient(); // 定义返回RequestInfo的mapper const someMapper: Mapper<RequestInfo> = (doc: Document) => { // 根据实际业务逻辑转换类型,此处为示例 return doc.name as unknown as RequestInfo; }; const someData: Document = { name: "test" }; const result = await myFunc(apiClient.inform, someData, someMapper); // 无类型错误
说明
- 泛型参数
P将inform的输入类型和mapper的输出类型绑定,确保两者类型一致,避免类型不兼容错误 - 全程无需使用any,在保持类型安全的同时实现了通用性
- 后续若inform的参数类型或mapper的返回类型变更,仅需调整泛型参数即可,核心逻辑无需修改
内容的提问来源于stack exchange,提问作者Camilo Penagos
相关产品推荐
相关产品推荐

