【问题标题】:Extend JavaScript object prototype by typescript class通过 typescript 类扩展 JavaScript 对象原型
【发布时间】:2016-03-14 13:25:01
【问题描述】:

tl;dr:我需要将编译后的 Typescript 原型定义应用于我定义为该类的对象。


情况: 我需要通过 typescript 类中定义的一些业务逻辑来扩展 JavaScript 对象。
这可能有点像:

class Address
{
  constructor(
    public Street: string,
    public Number: number,
    public Zip: number,
    public City: string)
  { }

  public get FullAddress()
  {
    return this.Street + ' ' + this.Number + ', '
      + this.Zip + ' ' + this.City;
  }
}

编译后的 JS 添加代码以将对象原型扩展为FullAddress。如果我打电话给new Address('Somestreet', 5, 3564, 'SomeCity'),一切都会像魅力一样。


问题:当我得到一些 JS 对象时(在我的例子中使用 angular 的 $http)

$http.get('/api/address').then((answer: AngularPromise<Address[]>) => 
{
  console.log(answer.data[0].FullAddress());
});

我可以在对象上调用函数FullAddress,因为在 Typescript 中,函数是在类定义中定义的。

现在,当我在浏览器中执行代码时,answer.data.FullAddress() 没有定义(这是有道理的,因为 Typescript 只提供了类型定义而从未接触过对象。


尝试的解决方案:一种可能的解决方案是为每个对象调用构造函数(有点像下面)

$http.get('/api/address').then((answer: AngularPromise<Address[]>) => 
{
  for(var i = 0; i < answer.data.length; i++)
  {
    answer.data[0] = new Address(answer.data[0].Street, ans.....);
  }
  console.log(answer.data[0].FullAddress());
});

并且可能重载Address 构造函数以接受完整的对象以减少样板。


实际问题:由于我需要的对象是一种比此处描述的简单地址构造更复杂的嵌套结构,因此上述解决方案需要我编写大量样板文件,我觉得必须有更好的解决方案来解决这个问题。

【问题讨论】:

    标签: javascript angularjs typescript prototype angular-http


    【解决方案1】:

    遇到了同样的问题!正如您所说,一种方法是创建一个构造函数并输入所有信息 - 有点乏味而且似乎是错误的。我们最终制作了一个MapTo 函数,可以将通用对象映射到强类:

    public static MapTo(jsonObject, nameSpace, classType) {
        var instance = new classType();
        for (var prop in jsonObject) {
            if (!jsonObject.hasOwnProperty(prop)) {
                continue;
            }
    
            if (jsonObject[prop] == null) {
                instance[prop] = null;
            } else if (typeof jsonObject[prop] === 'object') {
                if (nameSpace[prop]) {
                    instance[prop] = this.MapTo(jsonObject[prop], nameSpace, nameSpace[prop]);
                } else {
                    instance[prop] = jsonObject[prop];
                }
            } else {
                instance[prop] = jsonObject[prop];
            }
        }
    
        return instance;
    }
    

    而用法是:

    var strongAddress = MapTo(answer.data[0], Models, Models.Address); //I assumed your class was in a namespace called "Models"
    

    【讨论】:

    • 有趣的方法......仍然感觉有点不稳定,但已经好多了。我的问题是:我担心它只适用于内部模块,对吧(因为我在 Angular 和 NodeJS 上使用我的类,所以我只使用外部模块:|)
    猜你喜欢
    • 1970-01-01
    • 2011-09-25
    • 2021-07-31
    • 1970-01-01
    • 2017-11-21
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 2017-03-31
    相关资源
    最近更新 更多