Promise.all包装器具有元组类型

时间:2018-08-21 10:24:52

标签: typescript typescript3.0

我想创建一个包装来保证使用元组类型。我正要写这样的东西:

export function parallerRequest<TResponses extends any[]>(urls: string[]): Promise<TResponses> {
    return Promise.all<TResponses>(urls.map((url) => fetch(url)));
}

预期的行为应该是,当Promise.all将被解析时,返回的数据将具有提供的元组的形状。有什么想法可以实现这种行为吗?

1 个答案:

答案 0 :(得分:0)

即使Promise.all()在元组类型上进行了正确的映射(直到发布至少TypeScript 3.1才是supported),问题仍然是编译器无法验证在fetch上映射urls的结果将得到类型TResponses的值。它所知道的只是它将是Response[]类型,比TResponses宽。因此Promise.all返回Promise<Response[]>。如果要告诉编译器不要担心,可以使用type assertion

export function parallelRequest<TResponses extends Response[]>(
  urls: string[]
): Promise<TResponses> {
    return Promise.all(urls.map(x => fetch(x))) as Promise<TResponses>; // okay
}

这有效。但是请注意,编译器警告是一个很好的警告。您的parallelRequest()签名不会保证例如urlsTResponses的长度相同,或者不会有人为Response传递子类型TResponses的元素:

interface CustomResponse extends Response {
    prop: string;
}
parallelRequest<[Response, CustomResponse, Response]>(["/foo/bar", "/baz"]); // no error

所以这不是真正的安全类型。我不确定指定TResponses而不是仅保留Response[]的用例是什么,但是您应该小心。

无论如何,希望能有所帮助。祝你好运!