2017-07-13 5 views
6

Ich habe einen einfachen Dienst mit folgendem Inhalt:Typ 'Beobachtbar <Antwort | Beobachtbaren <Response>>‘ist nicht übertragbar auf dem Typ‚beobachtbar <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 || {}; 
    } 
} 

Es funktioniert perfekt, bis ich Typoskript von 2.3.4 auf 2.4 aktualisieren. 1.

nun nach dem Upgrade, ich bin die seltsamen Fehler bekommen:

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

Was hier ist der Punkt? Welche Änderungen an TS 2.4.x führen dazu, dass meine App nicht mehr ordnungsgemäß funktioniert?

+1

Warum aktualisieren Sie auf 2.4.x https://StackOverflow.com/Questions/44793859/RXJS-Subject-D-ts-error-Class-Subjectt-incorrectly-Extends-Base -klasse-obs/44793989 # 44793989 – CharanRoot

+0

@Jonnysai Ich bin mir nicht sicher, ob ich verstanden habe ... sagst du, dass ich nicht auf 2.4.1 upgraden kann? –

+1

handleSuccess = (Antwort: Antwort): Observable gibt keine Observable zurück, nur irgendwelche. Die Tatsache, dass Ihre Rückgabetypen falsch waren und jetzt der Compiler sich beschwert, ist ein gutes Zeichen. –

Antwort

5

TypeScript 2.4 eingeführt bessere Überprüfung für Generika. Es zeigt Fehler in Ihrem Code an, die behoben werden sollten.

Zum Beispiel entspricht der Rückgabetyp handleSuccess nicht dem, was zurückgegeben wird. Es gibt ein anonymes Objekt zurück, wird jedoch so eingegeben, als würde es Observable<Response> zurückgeben. Und weil es mit map verwendet wird, erhalten Sie eine zusammengesetzte Observable, die als Observable<Response | Observable<Response>> eingegeben wird.

Die Fehler, die Sie sehen, sind real und sollten behoben werden.

+0

Ein Observable wird von Ihrem handleSuccess NICHT zurückgegeben. Werfen Sie einen Blick auf die HTTP-Dokumentation https://tools.ietf.org/html/rfc2616#section-6 Sie geben eine Json-Payload zurück ... oder ein leeres Objekt. – JGFMK

1

Die Änderung ist stärker Typprüfung.

Ein Observable<Response> kann nicht einem Typ wie Response zugewiesen werden, da es sich um unterschiedliche Typen handelt. Der Kürze halber diese Typen nennen wir X und Y

Observable<X | Y> etwas getippt als Y nicht belegbar ist, weil, während es eine Y enthalten könnte es auch ein X enthalten könnten, und dies durch die strengeren abgelehnt wird Prüfung in Version 2.4.1 eingeführt

Erfassen Sie den Wert Ihres Ausdrucks in eine let Variable und geben Sie diese Variable zurück. Dann können Sie den Typ der Variablen überprüfen, der Ihnen anzeigt, dass er nicht kompatibel ist, genau wie der Compiler berichtet.

Um Ihren Code kompilieren zu lassen, sollten Sie vor dem Casting eine Instanz des korrekten Typs testen.

Wenn Sie Ihre Code-Basis nicht die Zeit zu reinigen haben bis Sie die Typprüfung mit stärkerer Wahl zurück können Sie --noStrictGenericChecks

Hier einig echter TS-Code mit einem Problem parallel. In diesem Beispiel fehlt FieldInstance eine Form-Eigenschaft, aber FormInstance hat eine und das ermöglicht mir, sie zu unterscheiden und die Typdeutigkeit zu behandeln. FieldInstanceRepeater kann FieldInstance zugewiesen werden, da es sich um einen Nachkommen handelt.

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

Betrachten Sie die folgenden Änderungen zu tun:

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

Die neueren Versionen von Typoskript stärker Typ/Generika Erkennung eingeführt, so dass, warum die Compiler über Ihre aktuellen Methoden beschwert, da ihre Rückgabetypen gerade nicht Spiel.

In der neuesten Version von eckig wurde der HTTP-Client neu erstellt, um das Parsing von nicht typisierten POJOs zu vermeiden (Aufruf r.json()).Zu diesem Zweck sind die neuen HTTP-Methoden generisch, sodass Entwickler beim Extrahieren des Antwortinhalts jetzt direkt in einen Typ mappen können. Weitere Informationen finden Sie unter this link

Verwandte Themen