我有以下基于Promise的TypeScript方法:
filterByParams(
query: Aggregate<any[]>,
params: ParamsObject
): Promise<Aggregate<any[]>> {
return this.findSomething(params)
.then<Aggregate<any[]>>((results: SomeResultType[]) => {
const matcher = {
// ... using results to match something
};
return query.match(matcher);
});
}
这个方法基本上是在(mongoose)聚合中添加一个过滤器,基于另一个查询的结果。
这个方法完全正常,而且Typescript很高兴。
问题
如果我尝试将其转换为使用async/await模式,TypeScript开始抱怨。这是转换后的方法:
async filterByParams(
query: Aggregate<any[]>,
params: ParamsObject
): Promise<Aggregate<any[]>> {
const results: SomeResultType[] = await this.findSomething(params);
const matcher = {
// ... using results to match something
};
return query.match(matcher);
}
这次我从Typescript得到了一个编译错误,位于return ...
行,告诉我:
TS2322:类型“any []”不可分配给类型“Aggregate< any[]>”
似乎Typescript无法从query.match(matcher)
函数中推断出正确的返回类型,即使将其转换为as Aggregate<any[]>
也没有帮助。
如果我从基于Promise的方法中删除then(..)
函数的泛型类型,则会得到与使用async/await语法时基本相同的错误。
我正在使用Typescript版本3.7.2
有人能解释一下为什么会发生这种情况,以及是否有解决方法可以在仍然能够使用async/await的情况下进行 - 而不必将代码的部分包装在promise中吗?我感觉自己已经尝试了每种类型的显式强制转换,但迄今为止都没有运气。
更新1
我将有问题的代码简化为:
async filterByParams(
query: Aggregate<any[]>
) {
return query;
}
尽管这个示例基本上什么也没做,但它仍然会引起编译错误。由于某种原因,async
关键字似乎只是解开了 Aggregate
类型。
与之相比,以下代码类似,但不会导致错误:
declare class SomeGenericClass<T> {}
async filterByParams(
query: SomeGenericClass<any[]>
) {
return query;
}
看起来问题与mongoose提供的Aggregate
类型有关。
any
有关。它会完全破坏类型检查链。由于查询本身具有any
,因此在使用query.match
时无法评估类型。这只是一种假设。如果您在 TypeScript playground 上提供最小可重现代码,那将更好。 - Eugene ObrezkovType 'SomeDocument[]' is not assignable to type 'Aggregate<SomeDocument[]>'
。我会尝试在在线游乐场中重现它。 - Nikolaj Dam LarsenfindSomething
是如何定义的?提供一个可重现的示例会很有帮助。 - Aleksey L.