【问题标题】:Type 'Observable<Response | Observable<Response>>' is not assignable to type 'Observable<Response>'输入“可观察的<响应 | Observable<Response>>' 不可分配给类型 'Observable<Response>'
【发布时间】:2017-12-18 22:27:56
【问题描述】:

我有一个简单的服务,内容如下:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';

import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AddressService {

  constructor(private http: Http) { }

  getAnything = (): Observable<Response> => {
    return this.http.get('https://my_api.com')
      .map(this.handleSuccess)
      .catch(this.handleError);
  }

  handleError = (error: Response): Observable<Response> => {
    return Observable.throw(error || 'Server Error');
  }

  handleSuccess = (response: Response): Observable<Response> => {
    let body;

    if (response.text()) {
      body = response.json();
    }

    return body || {};
  }
}

它运行良好,直到我将 Typescript 从 2.3.4 升级到 2.4.1。

现在,升级后,我收到了奇怪的错误:

Type 'Observable<Response | Observable<Response>>' is not assignable to type 'Observable<Response>'

这里有什么意义? TS 2.4.x 中有哪些更改使我的应用无法正常运行?

【问题讨论】:

  • 你为什么要升级到 2.4.x stackoverflow.com/questions/44793859/…
  • @Jonnysai 我不确定我是否理解...你是说我无法升级到 2.4.1?
  • handleSuccess = (response: Response): Observable 没有返回一个可观察的,只是任何一个。您的返回类型错误并且现在编译器抱怨这一事实是一个好兆头
  • 我猜错误在handleSuccess 函数中,它不返回Observable,它只返回类似对象的JSON,不是吗?

标签: angular typescript observable


【解决方案1】:

TypeScript 2.4 引入了更好的泛型检查。它突出显示代码中应该修复的错误。

例如,handleSuccess 的返回类型与其返回的内容不匹配;它返回一个匿名对象,但输入为返回Observable&lt;Response&gt;。因为它与map 一起使用,所以你最终会得到一个组合的observable,它的类型为Observable&lt;Response | Observable&lt;Response&gt;&gt;

您看到的错误是真实的,应该予以修复。

【讨论】:

【解决方案2】:

变化是更强的类型检查。

Observable&lt;Response&gt; 不能分配给键入为 Response 的内容,因为它们是不同的类型。为简洁起见,我们将这些类型称为 XY

Observable&lt;X | Y&gt; 不能分配给类型为 Y 的东西,因为虽然它可能包含 Y,但它也可能包含 X,这被 2.4.1 版中引入的更严格的检查拒绝

将表达式的值捕获到let 变量中并返回该变量。然后您将能够检查变量的类型,这将向您显示它不兼容,就像编译器报告的那样。

为了使您的代码编译,您应该在转换之前测试一个正确类型的实例。

如果你没有时间清理你的代码库,你可以使用--noStrictGenericChecks回拨更强的类型检查

这是一些真实的 TS 代码,其中存在与您的问题类似的问题。在此示例中,FieldInstance 缺少 Form 属性,但 FormInstance 有一个,这使我能够区分它们并处理类型歧义。 FieldInstanceRepeater 可分配给 FieldInstance,因为它是后代。

constructor(scope: FormInstance | FieldInstanceRepeater, field: IFormFieldRow) {
  this.FormInstance = ((function getFormInstance(fi: FormInstance | FieldInstance): FormInstance | FieldInstance {
    let isFormInstance = !!(fi as FormInstance).Form;
    return isFormInstance ? fi : getFormInstance((fi as FieldInstance).Scope);
  })(scope) as FormInstance);
  this.Scope = scope;
  ...
}

【讨论】:

    【解决方案3】:

    考虑进行以下更改:

    import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
    import { _throw } from 'rxjs/observable/throw';
    
    export interface Data{} // an interface to define the object in JSON format returned by your backend
    
    @Injectable()
    export class AddressService {
    
      constructor(private http: Http) { }
    
      getAnything = (): Observable<Data> => {
        return this.http.get('https://my_api.com')
          .map(this.handleSuccess)
          .catch(this.handleError);
      }
    
      handleError = (error: Response) : ErrorObservable { // The return type is ErrorObservable, which is a specialization of Observable<any>
        return _throw(error || 'Server Error');
      }
    
      handleSuccess = (response: Response) { // the return here is any, as you dont know how do the POJO(s) generated by response.json() look like
        let body;
    
        if (response.text()) {
          body = response.json();
        }
    
        return body || {};
      }
    }
    

    较新版本的 typescript 引入了更强大的类型/泛型检测,因此编译器为什么会抱怨您当前的方法,因为它们的返回类型不匹配。

    在最新版本的 Angular 中,重做 http 客户端以避免解析无类型 POJO(调用 r.json())。为此,新的 http 方法是通用的,因此开发人员现在可以在提取响应内容时直接映射到一个类型。欲了解更多信息,请查看this link

    【讨论】:

      猜你喜欢
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-22
      • 2019-04-22
      • 1970-01-01
      • 2021-08-17
      • 2019-01-10
      相关资源
      最近更新 更多