Typescript - 在类中转换默认方法而不创建类的新实例

时间:2017-09-16 02:04:17

标签: typescript casting

在从api到typescript类的类型转换json响应后,我无法访问该类的方法。

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 = [];
        }
    );
}

我收到如下错误消息: &#34; stock.convertDates不是函数&#34;。 如果我循环遍历响应中所有股票的列表并在调用&#34; convertDates&#34;之前为每个股票创建一个实例,则此工作没有任何错误。方法。这是代码:

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

1 个答案:

答案 0 :(得分:3)

TypeScript没有运行时强制转换。它有编译时type assertions。运行时强制转换和编译时类型断言之间的混淆似乎很常见;你的公司很好。

无论如何,你在编写

时使用了类型断言
response as Array<Stock>;

类型断言就是在告诉TypeScript编译器时,您知道的更多是关于对象类型在运行时的类型。上面,您告诉编译器response将是Stock个实例的数组。但是你已经厌倦了编译器,因为response是(我假设)实际上是一个不包含convertDates()函数属性的对象文字数组。因此,在运行时,您会收到错误stock.convertDates is not a function

TypeScript在运行时并没有真正做任何事情。如果需要Stock类的实例数组,则需要构建每个实例,就像在forEach()块中一样。如果你这样做,你的类型断言不再是谎言,你不会得到运行时错误。

通常,您希望尽可能少地使用类型断言;只使用它们来静音TypeScript编译器警告您100%确定在运行时不会出现问题。即使在这些情况下,通常最好重构代码以避免需要断言。例如:

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

可以在没有断言的情况下重写:

interface Person { name: string; age: string }

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

希望对你有意义。祝你好运!