【发布时间】:2021-11-18 00:05:29
【问题描述】:
我已经定义了一个函数,它接受另一个函数和一个参数列表作为参数来创建一个 Promise,如下所示:
async callbackToPromise (func: Function, ...args: any[]): Promise<any> {
// Immediately return if the function argument is undefined, to avoid errors.
if (func === undefined) {
console.warn('Function undefined in callbackToPromise.')
return await Promise.reject(
new Error('Function undefined in callbackToPromise.')
)
}
const call = new Promise((resolve, reject) => {
func((resolveStr: unknown) => {
if (resolveStr !== undefined) {
return resolve(resolveStr)
} else {
return reject(new Error('No data returned'))
}
}, ...args)
})
return await call
}
我使用此函数从我的环境中的大量 API 调用中获取承诺,它们都将回调作为第一个参数并且不返回任何内容(只是使用数据调用回调)。它们有多种附加参数,并以多种返回类型调用回调。
它通常运行良好,但有时我在编写我以前没有使用过的新 API 调用时会遇到一些挫折,因为 Typescript 无法告诉我要为 ...args 传递哪些参数,我必须花费额外的时间检查我为 API 构建的类型,以准确了解要传递的内容和方式。
在使用中,调用callbackToPromise的函数都定义了自己的参数,这就是我在接口代码之外使用的,但是如果我也可以在那里保持类型安全,那么在定义新的接口函数时会更方便.如果我意识到我的 API 类型文件中的输入错误或不完整并且需要更新,则更不容易出错。
有没有办法告诉Typescript“只接受...args匹配我作为func传入的函数的参数?
其他细节:
我正在调用 callbackToPromise 并使用我无法访问的黑盒函数,例如具有这样签名的函数(作为 window.external 的方法存在):
RemoveProblem: (
callback: Function,
prid: number,
stopDate: string,
isApproxDate: boolean,
reason: TProblemRemoveReason
) => void
我如何在代码中使用它的示例(较长函数定义的一部分):
const result: number = await this.helpers
.callbackToPromise(
this.wrappedWindow.external.RemoveProblem,
prid,
stopDate,
isApprox,
reason
)
.catch((error: Error) => {
console.error(`Error removing problem: ${error.message}`)
})
如果我尝试传递与作为第一个参数传递的函数不匹配的参数,我希望callbackToPromise 在编译时给出类型错误。
旁注:当我最初尝试在下面实现 CRice 的答案时,我遇到了一个问题,当我尝试使用 await 实际调用该函数时,Typescript 会说 Type 'number | void' is not assignable to type 'number'. Type 'void' is not assignable to type 'number'. 这最终不是由于Parameter<T> 部分脚本,但 .catch 部分的返回没有返回值。
Playground based on CRice's second example showing the error
【问题讨论】:
-
Don't use
anyunless you are in the middle of migrating from vanilla JS to TS。any在任何使用的地方都有效地禁用了打字稿。 -
不确定是否了解您的要求。你有一个预期结果的例子吗?因为据我了解,您想将函数 (func) 转换为 promise 吗?或者你只是想执行函数并返回它的结果?
-
@Mulan 我可以毫无问题地更改为
...args: unknown[],但是将返回类型更改为Promise<unknown>会导致我调用它的任何地方告诉我'未知不能分配给(无论类型)'。我知道回调将接收什么类型的参数,但不确定如何指定。
标签: typescript promise callback