TypeScript 构建一个 Promise.all 类函数 - 重载签名与函数实现不兼容

标签 typescript

通过使用 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 中实现重载函数有一些规则:

  1. 在调用点不考虑实现签名,它仅用于对实现进行类型检查(在记录 overloads in the handbook 的段落末尾提到)

  2. 实现签名必须具有与所有重载签名声明兼容的参数。实际上,这意味着每个参数类型必须是该参数位置的所有重载的所有参数类型的联合类型。

  3. 实现签名必须具有返回类型,它是所有重载返回类型的交集。实际上,这意味着实现必须在每个 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/

相关文章:

javascript - TypeError : formats. dateTimeString.toISOString 不是函数

typescript :实现联合类型

javascript - TypeScript 提示正确的 HTML5 Fullscreen API 方法

typescript - typescript 区分联合的 switch 语句的替代方法

typescript - 联合类型的组合

Javascript - 如何将缓冲区转换为字符串?

javascript - Webpack 并非所有源映射都显示 typescript

javascript - 通过扩展对象文字来实例化 Typescript 变量

typescript :将函数的参数约束为与特定类型的值关联的对象的键

带有继承的 Typescript 编译器错误泛型类型