【问题标题】:TypeScript generics: what if Promise reject and resolve types differ?TypeScript 泛型:如果 Promise 拒绝和解析类型不同怎么办?
【发布时间】:2018-01-21 07:48:27
【问题描述】:

处理错误和使用 Promises 的简单通用 Angular2+ 数据服务:

// imports skipped

class DataType {}

class Error {
  constructor(error: HttpResponse) {
    this.error = error.json()
  }
}


@Injectable()
export class MyService<DataType> {
  apiUrl = 'my/url';
  constructor(protected http) {}

  get(): Promise<DataType[] | Error> {
    return this.http
    .get(this.apiUrl)
    .toPromise()
    .then(response => response.json())
    .catch(this.handleError);
  }

  protected handleError(error: HttpResponse): Promise<Error> {
    console.error('An error occurred', error);
    return Promise.reject(new Error(error));  
  }
}

在这个类中,get 方法返回一个 Promise,它以 DataType[] 数组解析,并以 Error 类型拒绝。

编译这段代码,我得到这个错误:

键入'错误 | DataType[]' 不可分配给类型 'DataType'。类型“错误”不可分配给类型“数据类型”。

我使用的是 TypeScript 2.4.2 版。我确信这在 TypeScript 升级后开始发生,这使得类型检查更加严格。

我想知道如何在最新的 TypeScript 中处理不同类型的拒绝。这样做有不同的做法吗?

更新:我找到了相应的错误报告,尚未解决https://github.com/Microsoft/TypeScript/issues/7588

更新

我创建了一个 repo 来展示这个问题,有两个提交。第一次提交使用&lt;TypeResolve | TypeReject&gt; 方法,第二次只使用&lt;TypeResolved&gt;。这两个提交似乎都没有在现实生活中编译。

【问题讨论】:

  • promise 的泛型类型约束仅指resolve 类型。 reject 类型始终为 any
  • @NitzanTomer 在我看来你是不对的。 Typescript 期望 reject 类型与 resolve 类型相同
  • 不,它没有。无论解析类型如何,拒绝类型始终为any。当您说Promise&lt;string&gt; 时,只有解析类型是string,拒绝类型可以是任何类型(any
  • 你不想要Promise&lt;DataType[] | Error&gt;你只想要Promise&lt;DataType[]&gt;
  • @NitzanTomer @Ben 我创建了一个存储库,其中放置了无法以任何方式编译的代码,带有` |错误`或没有它。 github.com/easy-one/promise_typescript

标签: typescript angular-promise angular-services typescript2.0 typescript-generics


【解决方案1】:

Promise 的类型参数只是.resolve 的类型,而不是.reject 的类型。 .reject 的类型始终为 any,因为在编译时无法知道类型。造成这种情况的原因之一是 async 函数返回承诺,可能会拒绝他们的承诺,但有任何例外。

您应该改写Promise&lt;DataType[]&gt;,并在您处理错误的运行时检查错误类型。

【讨论】:

  • 我可能会弄错,但 Typescript 在我的情况下会引发异常。我希望这是他们会修复的错误
猜你喜欢
  • 2018-10-08
  • 1970-01-01
  • 2021-12-10
  • 2020-08-14
  • 1970-01-01
  • 2016-08-18
  • 2018-07-11
相关资源
最近更新 更多