"TypeScript和字段初始化器"
"TypeScript和字段初始化器"
如何在TS中这样初始化一个新类(以C#示例为例来说明我想要的):
// ... some code before return new MyClass { Field1 = "ASD", Field2 = "QWE" }; // ... some code after
admin 更改状态以发布 2023年5月22日
更新
自从撰写这个答案以来,有更好的方法出现了。请参阅下面有更多投票和更好答案的其他答案。由于被标记为已接受,我不能删除此答案。
旧答案
在 TypeScript 的 CodePlex 上有一个描述这个问题的问题: 支持对象初始化器。
如所述,您可以通过在 TypeScript 中使用接口而不是类来实现此目的:
interface Name { givenName: string; surname: string; } class Person { name: Name; age: number; } var bob: Person = { name: { givenName: "Bob", surname: "Smith", }, age: 35, };
更新于07/12/2016:Typescript 2.1推出了映射类型并提供了 Partial
,使您可以实现这个操作...
class Person { public name: string = "default" public address: string = "default" public age: number = 0; public constructor(init?:Partial) { 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 #样式了,(实际的字段初始化语法已被拒绝)。我更喜欢适当的字段初始化器,但似乎不会立即实现。
相比之下,如果您使用转换方法,则您的初始化器对象必须包含您要转换的类型的所有字段,而且不能获得类本身创建的任何类特定函数(或派生)。