【问题标题】:Typescript - casting default methods in class without creating new instance of the classTypescript - 在类中转换默认方法而不创建类的新实例
【发布时间】:2017-09-16 02:04:17
【问题描述】:

在将 json 响应从 api 转换为 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);
});

【问题讨论】:

标签: typescript casting


【解决方案1】:

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
} 

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-10
    • 2011-08-24
    • 2012-10-26
    • 2013-09-07
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多