Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

instantiate typescript class instance with values (object initialization)

Tags:

typescript

So in c# you can instantiate a class with values using the object initializer syntax. In TypeScript there doesn't appear to be the same kind of object initializer syntax. What I've found is that you can initialize values using the following two methods:

Constructor Initialization:

class MyClass {
  constructor(num: number, str: string) {
    this.numProperty = num;
    this.strProperty = str;
  }
  numProperty: number;
  strProperty: string;
}

let myClassInstance = new MyClass(100, 'hello');

Object Type Casting:

class MyClass {
  numProperty: number;
  strProperty: string;
}

let myClassInstance = <MyClass>{
  numProperty: 100,
  strProperty: 'hello'
};

While I like using Object Type Casting syntax in TypeScript, it only works with simple DTO classes that don't have methods you need to use. This is because casting doesn't actually create an object of the class type you are casting to.

Are there any other ways to do object initialization in TypeScript?

like image 367
Rafe Avatar asked Mar 06 '18 16:03

Rafe


1 Answers

If you like the "type casting" method but want to get an actual instance of the class, you can use Object.assign or a helper function like the following:

function init<T>(ctor: new () => T, props: Partial<T>): T {
  return Object.assign(new ctor(), props);
}

And you can use it like so:

class MyClass {
  public numProperty: number = 0;
  public strProperty: string = "";
  public worksWithMethodsToo() {
     console.log("numProperty: "+this.numProperty);
     console.log("strProperty: "+this.strProperty);
  }
}

let myClassInstance = init(MyClass, { numProperty: 100, strProperty: 'hello' });
myClassInstance.worksWithMethodsToo(); // works

There's also a version of the "constructor initialization" method that allows the constructor to be written more easily by using access modifiers like public or private on the parameters in the constructor signature to create what's called parameter properties:

class MyClass {
  // body of constructor is not necessary
  constructor(public numProperty: number, public strProperty: string) {}
}

let myClassInstance = new MyClass(100, 'hello');

That's more or less the same as your original MyClass (parameter names are different I guess), but it cuts down on the boilerplate code.


Does that help? Good luck.

like image 183
jcalz Avatar answered Nov 15 '22 05:11

jcalz