TypeScript-传递给构造函数整个对象

TypeScript-传递给构造函数整个对象,typescript,constructor,copy-constructor,Typescript,Constructor,Copy Constructor,我有一个脚本类型的类: export class Child { name:string; age:number; } 我想强制类实例只具有类声明具有的属性 例如,如果我从firebase获得一个对象: myFirebaseService.getChild(id).then(function(child){ var currentChild = new Child(child); }) 因此,当对象为:{name:“ben”,color:“db”}时,我希望结果为: curre

我有一个脚本类型的类:

export class Child {
  name:string;
  age:number;
}
我想强制类实例只具有类声明具有的属性

例如,如果我从firebase获得一个对象:

myFirebaseService.getChild(id).then(function(child){
  var currentChild = new Child(child);
}) 
因此,当对象为:{name:“ben”,color:“db”}时,我希望结果为:

currentChild = {"name":"ben"}
因为“颜色”不是“孩子”的领域

我试过这个:

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Ï;
    }
  }
}

,但我的truth类有许多字段,我需要简短的代码)

您在这里没有太多选择,因为您在构造函数未被转换为javascript之前在类中创建的成员定义,编译器将其省略:

class Child {
    name: string;
    age: number;

    constructor() {
        this.name = "name";
    }
}
汇编成:

var Child = (function () {
    function Child() {
        this.name = "name";
    }
    return Child;
}());
如您所见,
名称
成员是其中唯一的成员,甚至它也仅在分配给时使用

因为在运行时需要成员的名称,所以需要将它们放在一边,例如在数组中:

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


它没有经过测试,所以我不确定它是否正常工作,但如果您决定这样做,那么这就是您最需要的。

在我看来,从任意对象构建类实例的最干净的方法是使用分解结构。您仍然有所有字段的分配,但是您可以(非常干净地)控制如果字段不存在会发生什么,以及您将分配给类字段的字段:

export class Child {
  name:string
  age:number

  constructor({name = 'default name', age = 0} = {}) {
    this.name = name
    this.age = age
  }
}
现在,这允许您从
对象
s或
任何
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;
});
请尝试在中查看由此生成的内容

我们想要什么:

  • 一次性声明类字段
  • 我们班有很多方法
解决方案:

class Animal {
  name: string = 'default value';
  group: string = 'default value';

  constructor(data: Partial<Animal> = {}) {
    Object.assign(this, data)
  }

  echo() {
    return `My name is ${this.name}, I'm from: ${this.group}`;
  }
}

class Dog extends Animal {
  echo() {
    return super.echo() + ' from Dog class';
  }
}

const dog = new Dog({name: 'Teddy'});
console.log(dog.echo());
类动物{
名称:字符串='默认值';
组:字符串='默认值';
构造函数(数据:分部={}){
分配(此,数据)
}
回声(){
return`My name is${this.name},我来自:${this.group}`;
}
}
狗类动物{
回声(){
返回super.echo()+'来自Dog类';
}
}
const dog=新狗({name:'Teddy'});
console.log(dog.echo());
动物
-根类

Dog
-嵌套类


所有作品都没有打字脚本错误

我认为typescript 2.1的新功能可能对您很方便。@AlekseyL。不,因为他的问题是运行时问题。类似(不完全相同)的问题可能会有所帮助-检查此项:无需重复字段3次此解决方案将在
中复制
数据的所有属性
;如果我们想确保只复制类属性,最好的答案是BalázsÉdes one。