How to init a new class in TS in such a way (example in C# to show what I want):
// ... some code before return new MyClass { Field1 = "ASD", Field2 = "QWE" }; // ... some code after
Fields are initialized immediately before the constructor for the object instance is called. If the constructor assigns the value of a field, it will overwrite any value given during field declaration. For more information, see Using Constructors. A field initializer cannot refer to other instance fields.
But before we get into the main content, we need to clarify the concept of fields. A field is a variable declared directly in a class. See the article about constructors to understand how TypeScript assigns values to fields: TypeScript Constructors.
To initialize an object in TypeScript, we can create an object that matches the properties and types specified in the interface. export interface Category { name: string; description: string; } const category: Category = { name: "My Category", description: "My Description", };
Initialize Typed variable to an Empty Object in TypeScript # Use type assertions to initialize a typed variable to an empty object, e.g. const a1 = {} as Animal; . You can then set the properties on the object using dot or bracket notation. All of the properties you set on the object need to conform to the type.
Updated 07/12/2016: Typescript 2.1 introduces Mapped Types and provides Partial<T>
, which allows you to do this....
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"}), ];
Original Answer:
My approach is to define a separate fields
variable that you pass to the constructor. The trick is to redefine all the class fields for this initialiser as optional. When the object is created (with its defaults) you simply assign the initialiser object onto 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); } }
or do it manually (bit more safe):
if (fields) { this.name = fields.name || this.name; this.address = fields.address || this.address; this.age = fields.age || this.age; }
usage:
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 ];
and console output:
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 }
This gives you basic safety and property initialization, but its all optional and can be out-of-order. You get the class's defaults left alone if you don't pass a field.
You can also mix it with required constructor parameters too -- stick fields
on the end.
About as close to C# style as you're going to get I think (actual field-init syntax was rejected). I'd much prefer proper field initialiser, but doesn't look like it will happen yet.
For comparison, If you use the casting approach, your initialiser object must have ALL the fields for the type you are casting to, plus don't get any class specific functions (or derivations) created by the class itself.
Since writing this answer, better ways have come up. Please see the other answers below that have more votes and a better answer. I cannot remove this answer since it's marked as accepted.
There is an issue on the TypeScript codeplex that describes this: Support for object initializers.
As stated, you can already do this by using interfaces in TypeScript instead of classes:
interface Name { givenName: string; surname: string; } class Person { name: Name; age: number; } var bob: Person = { name: { givenName: "Bob", surname: "Smith", }, age: 35, };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With