能否为基于回调和参数生成Promise的函数实现TypeScript类型安全?
解决方案
通过TypeScript泛型+内置类型工具约束参数类型,即可实现类型检查和参数自动提示,改造后的代码如下:
// 定义符合业务场景的函数类型约束:第一个参数为接收返回值的回调,后续为自定义参数,无返回值 type CallbackFirstFunc<CallbackResult = unknown, RestParams extends any[] = any[]> = ( callback: (result: CallbackResult) => void, ...restParams: RestParams ) => void; async callbackToPromise<CallbackResult, RestParams extends any[]>( func: CallbackFirstFunc<CallbackResult, RestParams> | undefined, ...args: RestParams ): Promise<CallbackResult> { // 原有业务逻辑保持不变 if (func === undefined) { console.warn('Function undefined in callbackToPromise.') return Promise.reject( new Error('Function undefined in callbackToPromise.') ) } const call = new Promise<CallbackResult>((resolve, reject) => { func((resolveStr: CallbackResult) => { if (resolveStr !== undefined) { return resolve(resolveStr) } else { return reject(new Error('No data returned')) } }, ...args) }) return call }
实现逻辑
- 用泛型
CallbackResult指代回调函数接收的返回值类型,也就是最终Promise返回的结果类型,无需再手动标注any - 用泛型
RestParams指代目标函数除第一个回调外的所有参数类型集合,TypeScript会根据传入的func自动推导该类型 - 约束传入的
...args必须匹配RestParams,参数类型/数量不匹配时会直接触发编译报错,同时编辑器会自动提示参数类型
注意事项
之前遇到的Type 'number | void' is not assignable to type 'number'报错和本工具函数的类型逻辑无关,是catch块无返回值导致的,推荐用try/catch结构替代Promise链式catch写法避免该问题:
let result: number; try { result = await this.helpers.callbackToPromise( this.wrappedWindow.external.RemoveProblem, prid, stopDate, isApprox, reason ) } catch (error: Error) { console.error(`Error removing problem: ${error.message}`) // 按需选择抛出错误或者给result赋值默认值 throw error }
内容的提问来源于stack exchange,提问作者coppereyecat
相关产品推荐
相关产品推荐

