2017-07-13 67 views
6

我有以下內容簡單的服務:鍵入'Observable <Response |觀察到<Response>>」是不能分配給輸入‘觀察的<Response>’

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 || {}; 
    } 
} 

它是完美的工作,直到從2.3.4升級到打字稿2.4。 1。現在

,升級後,我發現了奇怪的錯誤:

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

有什麼意義嗎? TS 2.4.x中的哪些更改會使我的應用程序停止正常工作?

+1

你爲什麼要升級到2.4.x https://stackoverflow.com/questions/44793859/rxjs-subject-d-ts-error-class-subjectt-incorrectly-extends-base -class-obs/44793989#44793989 – CharanRoot

+0

@Jonnysai我不確定我是否理解......你是說我無法升級到2.4.1? –

+1

handleSuccess =(response:Response):Observable 不返回可觀察對象,只是任何。事實上,你的返回類型是錯誤的,現在編譯器抱怨是一個好兆頭 –

回答

5

TypeScript 2.4推出更好的檢查仿製藥。突出顯示應該修復的代碼中的錯誤。

例如,handleSuccess返回類型不匹配它返回;它返回一個匿名對象,但輸入爲返回Observable<Response>。並且因爲它與map一起使用,所以最終得到的輸入爲Observable<Response | Observable<Response>>

您所看到的錯誤是真實的,應該是固定的。

+0

您的handleSuccess不會返回可觀察的。 查看HTTP文檔https://tools.ietf.org/html/rfc2616#section-6 您正在返回json有效內容...或空對象。 – JGFMK

1

該變化是更強的類型檢查。

Observable<Response>是不能分配給一些類型爲Response,因爲它們是不同的類型。爲了簡便起見,您稱這些XY

Observable<X | 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; 
    ... 
} 
0

考慮做以下修改:

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 || {}; 
    } 
} 

打字稿較新版本的推出更強的類型/仿製藥的檢測,從而使編譯器爲什麼抱怨當前的方法,因爲它們的返回類型只是不比賽。

在angular的最新版本中,http客戶端重做以避免解析無類型的POJO(稱爲r.json())。爲此,新的http方法是通用的,因此開發人員現在可以在提取響應內容時直接映射到類型。爲進一步的信息看看this link

相關問題