能否从函数类型生成promisified类型,剔除回调参数保留其余参数?
实现自动生成Promise化的函数类型
要实现你需要的类型转换,我们可以利用TypeScript的条件类型和元组递归操作,精准过滤掉符合(error, result) => void格式的回调参数,并提取最终的Promise返回类型。
核心类型定义
// 判断是否是error-first风格的回调,若是则返回result的类型 type IsErrorFirstCallback<T> = T extends (error: any, result: infer R) => void ? R : never; // 过滤参数元组中的error-first回调,保留非回调参数 type FilterNonCallbackArgs<T extends any[]> = T extends [infer First, ...infer Rest] ? IsErrorFirstCallback<First> extends never ? [First, ...FilterNonCallbackArgs<Rest>] : FilterNonCallbackArgs<Rest> : []; // 提取所有error-first回调的result类型,组成数组 type ExtractErrorFirstResults<T extends any[]> = T extends [infer First, ...infer Rest] ? IsErrorFirstCallback<First> extends infer R ? R extends never ? ExtractErrorFirstResults<Rest> : [...ExtractErrorFirstResults<Rest>, R] : [] : []; // 获取数组的最后一个元素类型(取最后一个error-first回调的result作为Promise返回值) type GetLastResult<T extends any[]> = T extends [...infer _, infer Last] ? Last : never; // 最终的Promise化类型 type Promisify<T extends (...args: any[]) => void> = ( ...args: FilterNonCallbackArgs<Parameters<T>> ) => Promise<GetLastResult<ExtractErrorFirstResults<Parameters<T>>>>;
测试你的示例类型
// 原类型 type FuncLoad1 = (arg1: string, arg2: string, callback: (error: string | null, result: string | null) => void) => void; type FuncLoad2 = (arg1: string, callback: (error: string | null, result: string | null) => void, arg2: string) => void; type FuncLoad3 = (arg1: string, callbackInProgress: (progress: number) => void, arg2: string, callbackOnCompleted: (error: string | null, result: string | null) => void) => void; // 生成Promise化后的类型 type Promisified1 = Promisify<FuncLoad1>; // (arg1: string, arg2: string) => Promise<string | null> type Promisified2 = Promisify<FuncLoad2>; // (arg1: string, arg2: string) => Promise<string | null> type Promisified3 = Promisify<FuncLoad3>; // (arg1: string, arg2: string) => Promise<string | null>
说明
IsErrorFirstCallback:识别符合(error, result) => void格式的回调,返回其结果类型,否则返回never。FilterNonCallbackArgs:递归遍历函数参数元组,移除所有匹配的error-first回调参数,保留其他参数。ExtractErrorFirstResults:收集所有error-first回调的结果类型,用于后续取最终返回值。GetLastResult:取最后一个error-first回调的结果类型作为Promise的返回值(符合异步函数最终结果通常在最后一个回调的惯例)。Promisify:组合上述类型,生成最终的Promise化函数类型。
这个方案可以自动适配回调在任意位置、任意数量的情况,同时保留原参数的类型(包括模块内部私有类型)。
内容的提问来源于stack exchange,提问作者idchlife
相关产品推荐
相关产品推荐

