2016-05-14 111 views
16

我正在學習Angular2和Typescript。我正在研究angular.io上的英雄教程,但將其應用到我從ASP.Net轉換而來的項目中。我遇到了一個我認爲是因爲我缺乏理解的問題,但據我所知,它與本教程的相關部分相匹配。可觀察<{}>不可分配到類型可觀察<SomeType[]>

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

我收到以下錯誤就行了 「迴歸this.http.get(this.serviceUrl)」:

Error:(20, 16) TS2322: Type 'Observable<{}>' is not assignable to type 'Observable'. Type '{}' is not assignable to type 'RiskListSummary[]'. Property 'length' is missing in type '{}'.

如果它的確與衆不同,我使用webstorm(最新版本),但我認爲這個錯誤直接來自打字稿編譯器。我在想也許我需要一個rxjs的打字文件,但教程不使用一個,而我發現的「打字搜索」中找不到的打了個差別

以下是我對軟件包的依賴關係。 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" 

回答

18

我覺得你的問題就設在這裏:

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將指向在調用時的功能。

+0

謝謝,這個技巧就是這樣做的,我假設在原始示例中有.Net的擴展方法在工作(https: //angular.io/docs/ts/latest/guide/server-communication.html#)我想我需要開始一個新的項目,看看他們的例子是否仍然給出相同的錯誤 –

1

按照getRisks() FN,你是類型返回Observable<RiskListSummary[]>。但是,在您的代碼中,您將返回body.data || {}。我相信你需要將你的RiskListSummary []與你的body.data連接起來。

+0

是的,這也可以(我改變了簽名私人ExtractData由(RES:響應):RiskListSummary [])。作爲來自C#的新的JavaScript開發人員,它對我來說比lambda函數更有意義。我不太確定這個語言的含義還沒有說出哪個是最好的答案:-( –

1

我有同樣的問題,但無論我如何改變如上所述,它仍然無法正常工作。直到我的大學發現了​​這個map, catch defination as VSC prompted

所以適當的變化應該是這樣的(添加型投下面的地方)

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

我是新來的打字稿。所以這種[方法簽名]真的給我的頭:(

錘子但最後它的工作:)

-3

打字稿是一個編譯器工具,它總會給類型檢查的編譯錯誤如在這裏在這種情況下,getRisk方法應該指定它正在返回RiskListSummary類型的Observable,以便該工具能夠識別該方法期望的內容,並在訂閱方法中使用時檢查類型安全性。

+0

「Typescript is一個編譯器工具「?什麼? –

相關問題