2016 年 7 月 12 日更新:
Typescript 2.1 introduces Mapped Types 并提供Partial<T>,它允许你这样做......
class Person {
public name: string = "default"
public address: string = "default"
public age: number = 0;
public constructor(init?:Partial<Person>) {
Object.assign(this, init);
}
}
let persons = [
new Person(),
new Person({}),
new Person({name:"John"}),
new Person({address:"Earth"}),
new Person({age:20, address:"Earth", name:"John"}),
];
原答案:
我的方法是定义一个单独的fields 变量,并将其传递给构造函数。诀窍是将此初始化程序的所有类字段重新定义为可选。创建对象时(使用其默认值),您只需将初始化程序对象分配给this;
export class Person {
public name: string = "default"
public address: string = "default"
public age: number = 0;
public constructor(
fields?: {
name?: string,
address?: string,
age?: number
}) {
if (fields) Object.assign(this, fields);
}
}
或手动操作(更安全一点):
if (fields) {
this.name = fields.name || this.name;
this.address = fields.address || this.address;
this.age = fields.age || this.age;
}
用法:
let persons = [
new Person(),
new Person({name:"Joe"}),
new Person({
name:"Joe",
address:"planet Earth"
}),
new Person({
age:5,
address:"planet Earth",
name:"Joe"
}),
new Person(new Person({name:"Joe"})) //shallow clone
];
和控制台输出:
Person { name: 'default', address: 'default', age: 0 }
Person { name: 'Joe', address: 'default', age: 0 }
Person { name: 'Joe', address: 'planet Earth', age: 0 }
Person { name: 'Joe', address: 'planet Earth', age: 5 }
Person { name: 'Joe', address: 'default', age: 0 }
这为您提供了基本的安全和属性初始化,但它都是可选的并且可以是无序的。如果你不传递一个字段,你会得到类的默认值。
您也可以将它与所需的构造函数参数混合使用——最后贴上fields。
我认为与 C# 风格差不多 (actual field-init syntax was rejected)。我更喜欢适当的字段初始化程序,但看起来它不会发生。
为了比较,如果您使用转换方法,您的初始化对象必须具有您要转换为的类型的所有字段,并且不要获得由类本身创建的任何类特定函数(或派生)。