2017-09-16 61 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 

可以没有断言被改写。祝你好运!

相关问题