假设我有一个带有以下(最新)软件包的Typescript项目:
现在让我们说在我的项目中我定义了一个返回Promise的函数(由Typescript的原生环境声明定义):
import * as q from "q";
function doSomethingElseAsync(): Promise<number> {
return q.Promise<number>((resolve, reject) => {
setTimeout(() => resolve(1), 5000);
});
}
编译时,Typescript会抱怨以下错误:
error TS2322: Type 'Q.Promise<number>' is not assignable to type 'Promise<number>'.
Types of property 'then' are incompatible.
Type '<U>(onFulfill?: ((value: number) => IWhenable<U>) | undefined, onReject?: ((error: any) => IWhena...' is not assignable to type '<TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TR...'.
Types of parameters 'onFulfill' and 'onfulfilled' are incompatible.
Type '((value: number) => TResult1 | PromiseLike<TResult1>) | null | undefined' is not assignable to type '((value: number) => IWhenable<TResult1 | TResult2>) | undefined'.
Type 'null' is not assignable to type '((value: number) => IWhenable<TResult1 | TResult2>) | undefined'.
有一段时间,我认为这是因为Q Promises与Typescript的原生声明不兼容。但是,如果我将async
关键字添加到函数定义中,则错误将完全消失。
我对这种行为感到很困惑。这是Typescript,Q或Q类型中的错误吗?或者这是编译器的一些深奥但预期的行为?
答案 0 :(得分:0)
我的猜测是将async
关键字添加到您的函数会导致Javascript将该函数的返回值包装在本机Promise
中,以便函数返回一个promise或一个值,结果将是await
的承诺。
例如,它会执行以下操作:
Promise.resolve().then(() => doSomethingElseAsync())
如果没有async
关键字,您将返回q
承诺,该承诺不是原生Promise
的实例,因此您会收到类型错误。< / p>
我相信它也能正常工作(移除q
):
function doSomethingElseAsync(): Promise<number> {
return Promise<number>((resolve, reject) => {
setTimeout(() => resolve(1), 5000);
});
}
或者如果您的环境不包含本机Promise
类,也许更改返回类型可能会起作用,如下所示:
function doSomethingElseAsync(): q.Promise<number> {
return q.Promise<number>((resolve, reject) => {
setTimeout(() => resolve(1), 5000);
});
}
答案 1 :(得分:0)
看起来问题只是Q promises与async / await不兼容。
我尝试将异步功能的返回类型从原生Promise
交换到q.Promise
。编译器现在给我这个错误:
Type '<T>(resolver: (resolve: (val?: T | PromiseLike<T> | undefined) => void, reject: (reason?: any) =>...' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
Type '<T>(resolver: (resolve: (val?: T | PromiseLike<T> | undefined) => void, reject: (reason?: any) =>...' provides no match for the signature 'new <T>(executor: (resolve: (value?: T | PromiseLike<T> | undefined) => void, reject: (reason?: any) => void) => void): PromiseLike<T>'.
它表示返回类型“不是ES5 / ES3中的有效异步函数返回类型,因为它不引用与Promise兼容的构造函数值。”这是有道理的,因为q.Promise
不是可以使用new
调用的构造函数。相比之下,其他承诺实现(如Bluebird)确实具有兼容的构造函数。