2016-11-10 45 views
1

我有类型的脚本类:打字稿 - 传递给构造器,整个对象

export class Child { 
    name:string; 
    age:number; 
} 

我想迫使类实例有一个类声明只有性能。

例如,如果我从火力得到一个对象:

myFirebaseService.getChild(id).then(function(child){ 
    var currentChild = new Child(child); 
}) 

所以当对象是:{名称:“奔”,颜色:“DB”},我希望得到的结果是:

currentChild = {"name":"ben"} 

Becouse“color”不是“孩子”的字段。

我尝试这样做:

export class Child { 
    name:string; 
    age:number; 

    constructor(tempChild:Child = null) { 
    if (tempChild){ 
     for (var prop in tempChild) { 
     this[prop] = tempChild[prop]; 
     } 
    } 
    } 
} 

但它不能帮助。 “currentChild”获取所有字段并将它们附加到类实例。

(当然,我可以使用下面的代码:

export class Child { 
    name:string; 
    age:number; 

    constructor(tempChild:Child = null) { 
    if (tempChild){ 
     this.nam = tempChild.name; 
     this.age =tempChild.ageÏ; 
    } 
    } 
} 

,但我的心里话类有许多领域,我想短码)

+0

我认为typescript 2.1的新[keyof](https://github.com/Microsoft/TypeScript/pull/11929)功能可能对您很方便。 –

+0

@AlekseyL。不,因为他的问题是运行时问题。 –

回答

2

你不必这里有很多选择,因为您在构造函数之前在类中创建的成员定义没有被转换为javascript,编译器将它们排除在外:

class Child { 
    name: string; 
    age: number; 

    constructor() { 
     this.name = "name"; 
    } 
} 

编译成:

var Child = (function() { 
    function Child() { 
     this.name = "name"; 
    } 
    return Child; 
}()); 

正如你所看到的,name成员是那里唯一一个,即使分配给它时才使用。

因为你需要在运行系统中成员的名字,你需要让他们抛开,例如一个数组:

class Child { 
    private static MEMBERS = ["name", "age"]; 

    name: string; 
    age: number; 

    constructor(tempChild: Child = null) { 
     if (tempChild) { 
      for (var prop in tempChild) { 
       if (Child.MEMBERS.indexOf(props) >= 0) { 
        this[prop] = tempChild[prop]; 
       } 
      } 
     } 
    } 
} 

这是不是很舒服的工作,所以你可以使用装饰器。
例如:

function member(cls: any, name: string) { 
    if (!cls.constructor.MEMBERS) { 
     cls.constructor.MEMBERS = []; 
    } 

    cls.constructor.MEMBERS.push(name); 
} 

function isMember(cls: any, name: string): boolean { 
    return cls.MEMBERS[name] != null; 
} 

class Child { 
    @member 
    name: string; 

    @member 
    age: number; 

    constructor(tempChild: Child = null) { 
     if (tempChild) { 
      for (var prop in tempChild) { 
       if (isMember(Child, prop)) { 
        this[prop] = tempChild[prop]; 
       } 
      } 
     } 
    } 
} 

code in playground

这不是测试,所以我不知道它的工作,但如果你决定走那条路那么它就是你最需要什么。

-1

在我看来,从任意对象构建类实例的最简洁的方法是使用解构。你还有您的所有领域的任务,但你有过,如果该字段不存在,会发生什么(很干净)控制,并哪些领域你会分配给你的类字段:

export class Child { 
    name:string 
    age:number 

    constructor({name = 'default name', age = 0} = {}) { 
    this.name = name 
    this.age = age 
    } 
} 

现在,这让你从Object S或any S或任何部分对象文本创建实例,但使用文字时,它不会让你添加额外的东西,这好像是你需要的东西:

const c0 = new Child({} as any /* as Object works as well */) 
const c1 = new Child({}) // Literal, will be using defaults 
const c2 = new Child() // No argument, using defaults only 
const c3 = new Child({ name: 'a', age: 1 }) 
const c4 = new Child({ name: 'b', foo: 'bar'}) // error with foo 

生成JS将检查一切你会手动检查:

define(["require", "exports"], function (require, exports) { 
    "use strict"; 
    var Child = (function() { 
     function Child(_a) { 
      var _b = _a === void 0 ? {} : _a, _c = _b.name, name = _c === void 0 ? 'default name' : _c, _d = _b.age, age = _d === void 0 ? 0 : _d; 
      this.name = name; 
      this.age = age; 
     } 
     return Child; 
    }()); 
    exports.Child = Child; 
}); 

请尝试看看playground这是什么产生的!