通过使用 TypeScript,任何人都可以使用 sequentially
应该强制传递1到N个参数,其中输入Promise<T>
等于输出[Promise<T>,..
[不工作] 当以下列方式重载第一个声明时,我在第一个声明中遇到 tslint 错误:
Overload signature is not compatible with function implementation. ts(2394)
promise.ts
function sequentially<T1>(promiseWrappers: [
() => Promise<T1>
]): Promise<[T1]>;
async function sequentially<T1, T2>(promiseWrappers: [
() => Promise<T1>,
() => Promise<T2>
]): Promise<[T1, T2]> {
const resolved = [];
for (const wrapper of promiseWrappers) {
resolved.push(await wrapper());
}
// @ts-ignore
return resolved;
}
[工作] 似乎唯一可行的方法是在使用 .js
编写实现时和一个单独的声明文件 .d.ts
,如下所示:
promise.js
export async function sequentially(promiseWrappers) {
const resolved = [];
for (const wrapper of promiseWrappers) {
resolved.push(await wrapper());
}
return resolved;
}
promise.d.ts
export declare function sequentially<T1, T2>(promiseWrappers: [
() => Promise<T1>,
() => Promise<T2>
]): Promise<[T1, T2]>;
export declare function sequentially<T1, T2, T3>(promiseWrappers: [
() => Promise<T1>,
() => Promise<T2>,
() => Promise<T3>
]): Promise<[T1, T2, T3]>;
如何解决第一个 TS 实现案例?
最佳答案
在 TypeScript 中实现重载函数有一些规则:
在调用点不考虑实现签名,它仅用于对实现进行类型检查(在记录 overloads in the handbook 的段落末尾提到)
实现签名必须具有与所有重载签名声明兼容的参数。实际上,这意味着每个参数类型必须是该参数位置的所有重载的所有参数类型的联合类型。
实现签名必须具有返回类型,它是所有重载返回类型的交集。实际上,这意味着实现必须在每个 return 语句中进行类型转换,或者只是将实现返回类型声明为 any。
我在任何地方都找不到 2 和 3 的记录,但它们遵循函数类型兼容性的一般变体规则以及实现签名必须与所有重载声明兼容的事实。
这是代码,它在 --strictFunctionTypes
和 --noImplicitAny
开启的情况下编译
function sequentially<T1>(promiseWrappers: [
() => Promise<T1>
]): Promise<[T1]>;
function sequentially<T1, T2>(promiseWrappers: [
() => Promise<T1>,
() => Promise<T2>,
]): Promise<[T1, T2]>;
async function sequentially<T1, T2>(promiseWrappers: [
() => Promise<T1>,
] | [
() => Promise<T1>,
() => Promise<T2>
]): Promise<[T1, T2] & [T1]> {
const resolved = [] as unknown as [T1, T2] & [T1];
for (const wrapper of promiseWrappers) {
resolved.push(await wrapper());
}
return resolved;
}
关于TypeScript 构建一个 Promise.all 类函数 - 重载签名与函数实现不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55778230/