【问题标题】:Observable<{}> not assignable to type Observable<SomeType[]>Observable<{}> 不可分配给类型 Observable<SomeType[]>
【发布时间】:2016-09-10 07:17:04
【问题描述】:

我正在学习 Angular2 和 Typescript。我正在研究 angular.io 上的 Heroes 教程,但将其应用于我从 ASP.Net 转换的项目。我遇到了一个问题,我认为这是由于我缺乏理解,但据我所知,它与教程的相关部分正在做的事情相匹配。

import { Injectable } from '@angular/core';
import {RiskListSummary} from '../Models/RiskListSummary';
import { Observable } from 'rxjs/Rx';
import { Http, Response } from '@angular/http';

@Injectable()
export class RiskAssessmentListService {

    constructor(private http : Http) {}

    private serviceUrl = "http://myserviceurl/";

    getRisks(): Observable<RiskListSummary[]> {
        return this.http.get(this.serviceUrl)
            .map(this.extractData())
            .catch(this.handleError());
    }

    private extractData(res: Response) {
       if (res.status < 200 || res.status >= 300) {
             throw new Error('Bad response status: ' + res.status);
           }
       let body = res.json();
       return body.data || { };
    }

    private handleError (error: any) {
        let errMsg = error.message || 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }
}

我在“return this.http.get(this.serviceUrl)”这一行收到以下错误:

错误:(20, 16) TS2322: Type 'Observable' is notassignable to type “可观察”。类型“{}”不可分配给类型 '风险列表摘要 []'。类型“{}”中缺少属性“长度”。

如果有什么不同,我使用的是 webstorm(最新版本),但我认为这个错误直接来自 typescript 编译器。我在想也许我需要一个 rxjs 的类型文件,但本教程没有使用一个,而且我通过“类型搜索”找到的文件都没有产生任何影响

以下是我在 package.json 中的依赖项:

  "dependencies": {
    "@angular/common":  "2.0.0-rc.1",
    "@angular/compiler":  "2.0.0-rc.1",
    "@angular/core":  "2.0.0-rc.1",
    "@angular/http":  "2.0.0-rc.1",
    "@angular/platform-browser":  "2.0.0-rc.1",
    "@angular/platform-browser-dynamic":  "2.0.0-rc.1",
    "@angular/router":  "2.0.0-rc.1",
    "@angular/router-deprecated":  "2.0.0-rc.1",
    "@angular/upgrade":  "2.0.0-rc.1",

    "systemjs": "0.19.27",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "^0.6.12"

【问题讨论】:

    标签: typescript angular rxjs


    【解决方案1】:

    我认为你的问题出在这里:

    getRisks(): Observable<RiskListSummary[]> {
      return this.http.get(this.serviceUrl)
         .map(this.extractData()) <== passing result of function
         .catch(this.handleError()); <== passing result of function
    }
    

    您可以只使用传递 function 参考:

    getRisks(): Observable<RiskListSummary[]> {
      return this.http.get(this.serviceUrl)
         .map(this.extractData)
         .catch(this.handleError);
    }
    

    但是这样你会失去this

    或者你可以使用bind方法来保留this

    getRisks(): Observable<RiskListSummary[]> {
      return this.http.get(this.serviceUrl)
        .map(this.extractData.bind(this))
        .catch(this.handleError.bind(this));
    }
    

    不过你会lose type checking

    我会利用arrow 函数来使用lexical this

    getRisks(): Observable<RiskListSummary[]> {
      return this.http.get(this.serviceUrl)
        .map(res => this.extractData(res))
        .catch(err => this.handleError(err));
    }
    

    没有它,this 变量将指向进行调用的函数,而不是包含 getRisks() 的实例。

    【讨论】:

    【解决方案2】:

    我遇到了同样的问题,但是无论我如何如上所述更改,它仍然无法正常工作。直到我的大学发现这个map, catch defination as VSC prompted

    所以正确的更改应该是这样的(在以下位置添加类型转换)

    getRisks(): Observable<RiskListSummary[]> {
      return this.http.get(this.serviceUrl)
        .map<RiskListSummary[]>(this.extractData)
        .catch<RiskListSummary[]>(this.handleError);
    }
    

    我是 TypeScript 的新手。所以这种【方法签名】真的是给我敲了敲头:(

    但最后还是成功了:)

    【讨论】:

      【解决方案3】:

      根据getRisks() fn,您是返回Observable&lt;RiskListSummary[]&gt; 的类型。但是在您的代码中,您将返回 body.data || {}。我相信您需要将 RiskListSummary[] 连接到您的 body.data。

      【讨论】:

      • 是的,这也有效(我将签名更改为私有 extractData(res: Response) : RiskListSummary[])。作为一个来自 C# 的新 javascript 开发人员,它对我来说也比 lambda 函数更有意义。我还不确定哪种语言是最好的答案:-(
      【解决方案4】:

      我找到了下一个:AccessTokens 丢失。所以,我做了改变,它奏效了: 在您的模型上(在我的情况下为国家/地区)编辑 de 文件并从以下位置更改:

      export interface CountryInterface {
        "id"?: any;
        "name": string;
        "order"?: number;  
      }
      
      export class Country implements CountryInterface {
        "id": any;
        "name": string;
        "order": number;
         ....
      }
      

      收件人:

      export interface CountryInterface {
        "id"?: any;
        "name": string;
        "order"?: number;
        accessTokens: any[];
      }
      
      export class Country implements CountryInterface {
        "id": any;
        "name": string;
        "order": number;
        accessTokens: any[];
        ...
      }
      

      【讨论】:

        猜你喜欢
        • 2018-08-14
        • 2021-01-02
        • 2020-11-23
        • 2019-01-12
        • 1970-01-01
        • 2023-04-10
        • 2018-03-09
        • 2020-07-28
        • 2021-10-28
        相关资源
        最近更新 更多