arrays - Typescript - 具有不同返回值的动态承诺数组
问题描述
谁能帮我解决这段代码有什么问题?Promise.all
我在底部找不到合适的类型来拨打电话。它也尝试过Promise.all<Services[], PullRequests[]>(ops)
,但PullRequests[]
不能是可选的......
function wait<Twait>(time: number, response: Twait): Promise<Twait> {
return new Promise(resolve => setTimeout(() => resolve(response), time))
}
interface Service {
name: string;
id: number;
}
async function getServices(): Promise<Service[]> {
const response = await wait(400, { "id": 200 });
return [{ name: "service", id: response.id }]
}
interface PullRequest {
prType: string;
githubId: number;
}
async function getPrs(): Promise<PullRequest[]> {
const response = await wait(400, { "githubId": 200 });
return [{ prType: "foo", githubId: response.githubId }]
}
async function main(): Promise<void> {
const ops: [ PromiseLike<Service[]>, PromiseLike<PullRequest[]>? ] = [getServices()]
if (Math.random() > 0.5) { // <== this is random on purpose.
ops.push(getPrs())
}
const [ services, prs ] = await Promise.all(ops) // This throws a ts compile error (attached below)
console.log("services:")
console.log(services)
console.log("prs:")
console.log(prs)
}
No overload matches this call. The last overload gave the following error.
Argument of type '[PromiseLike<Service[]>, (PromiseLike<PullRequest[]> | undefined)?]' is not assignable to parameter of type 'Iterable<Service[] | PromiseLike<Service[] | undefined> | undefined>'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
Type 'IteratorResult<PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined, any>' is not assignable to type 'IteratorResult<Service[] | PromiseLike<Service[] | undefined> | undefined, any>'.
Type 'IteratorYieldResult<PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined>' is not assignable to type 'IteratorResult<Service[] | PromiseLike<Service[] | undefined> | undefined, any>'.
Type 'IteratorYieldResult<PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined>' is not assignable to type 'IteratorYieldResult<Service[] | PromiseLike<Service[] | undefined> | undefined>'.
Type 'PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined' is not assignable to type 'Service[] | PromiseLike<Service[] | undefined> | undefined'.
Type 'PromiseLike<PullRequest[]>' is not assignable to type 'Service[] | PromiseLike<Service[] | undefined> | undefined'.
Type 'PromiseLike<PullRequest[]>' is not assignable to type 'PromiseLike<Service[] | undefined>'.
Type 'PullRequest[]' is not assignable to type 'Service[]'.
Type 'PullRequest' is missing the following properties from type 'Service': name, id
解决方案
根据microsoft/TypeScript#28427 ,看起来像是 TS 库定义中的一个已知问题。目前,该库硬编码了一堆不包含可选元素的特定元组类型。已经采取了一些努力来解决这个问题,但显然PromiseLike
类型以及它们如何交互await
已经足够复杂,以至于尚未接受任何修复此问题的拉取请求。microsoft/TypeScript#39788 中的评论解释说,切换它可能会破坏依赖于当前定义的现有现实世界代码。
直到并且除非这在上游得到解决,否则您可以使用声明合并来添加您自己的签名,因为Promise.all()
它只是将承诺映射到传入的数组或元组的元素上:
interface PromiseConstructor {
all<T extends readonly any[]>(
values: { [K in keyof T]: T[K] | PromiseLike<T[K]> }
): Promise<T>;
}
您可以测试它是否符合您的要求:
const promiseAllOps = Promise.all(ops); // no error now
// const promiseAllOps: Promise<[Service[], (PullRequest[] | undefined)?]>
const awaitPromiseAllOps = await promiseAllOps;
// const awaitPromiseAllOps: [Service[], (PullRequest[] | undefined)?]
const [services, prs] = awaitPromiseAllOps;
services; // Service[]
prs; // PullRequest[] | undefined
推荐阅读
- python - Python 3,用科学记数法打印列表
- android - 刷卡或强制关闭应用时未收到 FCM 通知
- ajax - 为什么打印 Xpath 而不是元素内的文本?
- java - Apache tomcat 7 在 localhost 上运行良好,但部署的 war 文件在尝试运行时抛出异常
- javascript - 使用断点进行调试与使用 console.log 进行调试有何不同?
- python-3.x - 使用带有 PIL 的 Tkinter 文本小部件的外部字体文件
- javascript - 比较两个对象数组并合并
- nginx - Nginx 指向错误的文件夹位置
- node.js - 节点 JS 发布消息
- angular - rxjs/Rx 没有导出成员 forkjoin