TypeScript - 传递给构造函数整个对象
Posted
技术标签:
【中文标题】TypeScript - 传递给构造函数整个对象【英文标题】:TypeScript - pass to constructor entire object 【发布时间】:2017-03-24 02:49:48 【问题描述】:我在 type script 有一门课:
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"
因为“color”不是“child”的字段。
我试过了:
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Ï;
,但是我的真值类有很多字段,我想要短代码)
【问题讨论】:
我认为 typescript 2.1 的 keyof 新功能可能对您很方便。 @AlekseyL。不,因为他的问题是运行时问题。 可能有帮助的类似(不相同)问题 - ***.com/questions/22875636/… 【参考方案1】:您在这里没有太多选择,因为您在构造函数之前在类中所做的成员定义没有被翻译成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)
它没有经过测试,所以我不确定它是否有效,但如果你决定这样做,那么它就是你需要的大部分。
【讨论】:
【参考方案2】:在我看来,从任意对象构建类实例的最简洁方法是使用解构。您仍然有所有字段的分配,但是您可以(非常干净)控制如果该字段不存在会发生什么,以及您将分配给您的类字段的字段:
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 中查看由此生成的内容!
【讨论】:
检查这个:***.com/a/58788876/2746447 不需要重复字段 3 次【参考方案3】:我们想要什么:
一次性声明类字段 在我们的类中有方法解决方案:
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());
Animal
- 根类
Dog
- 嵌套类
所有作品都没有打字错误
【讨论】:
此方案将this
复制data
的所有属性;如果我们想确保只复制类属性,最好的答案是 Balázs Édes one。以上是关于TypeScript - 传递给构造函数整个对象的主要内容,如果未能解决你的问题,请参考以下文章