TypeScript 泛型:如果 Promise 拒绝和解析类型不同怎么办?

Posted

技术标签:

【中文标题】TypeScript 泛型:如果 Promise 拒绝和解析类型不同怎么办?【英文标题】:TypeScript generics: what if Promise reject and resolve types differ? 【发布时间】: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 【参考方案1】:

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

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

【讨论】:

我可能会弄错,但 Typescript 在我的情况下会引发异常。我希望这是他们会修复的错误

以上是关于TypeScript 泛型:如果 Promise 拒绝和解析类型不同怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

Typescript泛型类型约束和类型兼容性

typeScript函数篇

TypeScript--泛型

TypeScript--泛型

TypeScript教程# 15:泛型

将接口中的字段类型替换为 Promise