从构造函数初始化Typescript类值

时间:2013-05-28 13:35:36

标签: inheritance constructor typescript

我正在使用TypeScript创建一些使用KnockoutJS的类,数据是从WebAPI返回的一些JSON加载的。

问题是我想从构造函数中将JSON值复制到我的TypeScript类中:但是如果我只在基类上执行此操作,则尚未定义继承的属性,因此不会初始化。

实施例

我们想要从JSON响应中创建一个库存项目:

{ Name: "Test", Quantity:1, Price: 100 }

我有一个基类Product和一个继承类Inventory:

export class Product {
  Name = ko.observable("");

  constructor(source) {
    // a utility that copies properties into this instance
    utils.CopyProperties(source,this);
  }

export class Inventory extends Product {
  Quantity = ko.observable(0);
  Price = ko.observable(0);

  constructor(source) {
    super(source); // call base c'tor
    // the quantity and price properties are only now defined
  }
}

Inventory的属性仅在 super 构造函数调用之后的JS输出代码中创建,因此在执行Product构造函数时不存在。

我能看到的唯一解决方案是从构造函数中取出初始化值,但我并不喜欢这种方法,尽管我怀疑它是唯一的选择。

  var inventoryItem = new Inventory();
  inventoryItem.LoadFrom(source);

3 个答案:

答案 0 :(得分:11)

最好我可以想出让你有一个从构造函数调用的基本反序列化例程(修改为删除敲除依赖项以进行测试):

class utils {
    public static CopyProperties(source:any, target:any):void {
        for(var prop in source){
            if(target[prop] !== undefined){
                target[prop] = source[prop];
            }
            else {
                console.error("Cannot set undefined property: " + prop);
            }
        }
    }
}

class Product {
  Name = "Name";

  constructor(source) {
    this.init(source);
  }

  init(source){
     utils.CopyProperties(source,this);
  }
}

class Inventory extends Product {
  Quantity;
  Price;

  constructor(source) {
    super(source);
  }

  init(source){
      this.Quantity = 0;
      this.Price = 0;
      super.init(source);
  }
}

var item = new Inventory({ Name: "Test", Quantity: 1, Price: 100 });

奇怪,变量仅在调用super()后在JS中初始化。也许值raising a work item on codeplex

Playground

答案 1 :(得分:3)

这种方法似乎对我有用:

/// <reference path="knockout.d.ts" />

export class Product {
    Name: KnockoutObservableString;

    constructor(source) {
        this.Name = ko.observable(source.Name);
    }
}

export class Inventory extends Product {
    Quantity: KnockoutObservableNumber;
    Price: KnockoutObservableNumber;

    constructor(source) {
        super(source);
        this.Quantity = ko.observable(source.Quantity);
        this.Price = ko.observable(source.Price);
    }
}

var item = new Inventory({ Name: "Test", Quantity: 1, Price: 100 });

答案 2 :(得分:0)

@JcFx

此变量测试在分配值之前始终未定义。

  

if(target[prop] !== undefined){

您可能希望将此if语句设为&#39; true&#39;,或者使用此代码:

for (const prop of Object.keys(source)) {
  this[prop] = source[prop];
}

关于forin,请看这个链接: https://github.com/angular/tsickle/issues/125