2017-09-16 59 views
0

從類api到類型轉換類的類型轉換json響應後,我無法訪問該類的方法。Typescript - 在沒有創建類的新實例的情況下在類中轉換默認方法

class Stock { 
    name: String; 
    purchaseDate: Date; 
    constructor() {} 
    convertDates() { 
     this.purchaseDate = new Date(this.purchaseDate); 
    } 
} 
getAll() { 
    return this.http.get(URL + '/find').map(
     (response) => { 
      this.stocks = response as Array<Stock>; 
      _.forEach(this.stocks, (stock) => { 
       stock.convertDates(); 
      } 
     }, 
     (error) => { 
      this.stocks = []; 
     } 
    ); 
} 

我如下得到一個錯誤信息: 「stock.convertDates不是一個函數」。 如果我通過響應中的所有股票列表循環並在調用「convertDates」方法之前爲每個股票創建一個實例,則此工作原理沒有任何錯誤。下面是它的代碼:

_.forEach(response, (stock) => { 
    let newstock = new Stock(); 
    _.merge(newstock, stock); 
    newstock.convertDates(); 
    this.stocks.push(newstock); 
}); 
+0

查看關於此問題的接受答案,它解釋了您遇到的問題。 https://stackoverflow.com/questions/22875636/how-do-i-cast-a-json-object-to-a-typescript-class – supersighs

回答

3

TypeScript沒有運行時轉換。它有編譯時間type assertions。運行時間轉換和編譯時類型斷言之間的混淆似乎相當普遍;你在一個很好的公司。

反正你使用的類型聲明,當你寫

當你告訴編譯器打字稿,你知道的比它關於對象的類型會在運行時什麼
response as Array<Stock>; 

類型斷言。上面,你告訴編譯器response將是一個Stock實例的數組。但是你騙了編譯器,因爲response是(我假設)實際上是一個不包含convertDates()函數屬性的對象文字數組。所以在運行時你會得到錯誤stock.convertDates is not a function

TypeScript在運行時並沒有做任何事情。如果您想要一組Stock類的實例,則需要構造每個實例,就像在forEach()塊中所做的那樣。如果你這樣做,你的類型斷言不再是謊言,你不會得到一個運行時錯誤。


一般要儘量少使用類型斷言;只使用它們來沉默TypeScript編譯器,警告您100%確定在運行時不會成爲問題。即使在這些情況下,通常最好重構代碼以避免需要斷言。例如:

interface Person { name: string; age: string } 

//no need to assert; TypeScript believes the declaration 
const person: Person = { 
    name: 'Stephen King', 
    age: 69 
} 

。希望對你有意義:

interface Person { name: string; age: string } 

//need to assert below because {} is not a Person 
const person: Person = {} as Person; 

//populate fields so your assertion is not a lie 
person.name = 'Stephen King'; 
person.age = 69 

可以沒有斷言被改寫。祝你好運!

相關問題