How to initialize an object in TypeScript

Typescript

Typescript Problem Overview


I have a simple model class

export interface Category {

  name: string;
  description: string;

}

I need to declare and initialize a variable in an angular component. Tried:

category: Category = {};

Error: {} is not assignable to a Category

category: Category = new Category();

error: Category refers to a type, but being referred as value..

Any suggestions?

Typescript Solutions


Solution 1 - Typescript

There are a number of ways to solve this problem, depending on your desired result.

Way 1: Convert your interface to a class
export class Category {
  name: string;
  description: string;
}
const category: Category = new Category();
Way 2: Extend your interface as a class
export class CategoryObject implements Category {
}
const category: Category = new CategoryObject();
Way 3: Fully specify your object, matching the interface
const category: Category = {
  name: 'My Category',
  description: 'My Description',
};
Way 4: Make the properties optional
export interface Category {
  name?: string;
  description?: string;
}

const category: Category = {};
Way 5: Change your variable's type to use Partial<T>
export interface Category {
  name: string;
  description: string;
}

const category: Partial<Category> = {};

Solution 2 - Typescript

If you don't want to change your definition from interface to class, you could also do:

let category = <Category>{ };

Otherwise, you could follow other answers and change your Category to be a class.

edit: as per ruffin's comment below, if the interface is

export interface ITiered { one: { two: { three: function (x) {...} } } } 

and you try let x = {} as ITiered, then you'll have an error when you call something like x.one.two.three()

Solution 3 - Typescript

In Typescript if you want to use Object Initializer you need to define all properties in the class.

let category: Category = {
    name: '',
    description: ''
};

With this way your model still can be remain as an interface.

Solution 4 - Typescript

export interface Category {
  name: string;
  description: string;
}


category = {} as Category ;

Edit: Wanted to put the comment below in the answer so people know why my answer is wrong. I was assuming you would always assign right after, but that's not a good assumption to make.

> now you have an object in your system that is assumed to be of some type, but with some required properties missing. this is just bad advice causing errors somewhere down the line.

Solution 5 - Typescript

Your object literal must match the interface. Since your interface has two required properties (name and description) they must both be declared when the object is instantiated.

const category: Category = {
    name: 'foo',
    description: 'bar'
};

If you cannot construct the entire object up front you can use the builtin Partial type to build the object.

const builder: Partial<Category> = {};
builder.name = 'foo';
builder.description = 'bar';

const category: Category = builder as Category;

Solution 6 - Typescript

Like C# class:

export class Category {
    category: number = null;
    description: string = null;
    name: string = null;

  public constructor(init?: Partial<Category>) {
        Object.assign(this, init);
}
}

Now when you create a new instance all field names are disponible and empty.

 const instance_of_category: Category = new Category();

now you have emty class object with all fields defined like c#:

instance_of_category{
    "category": null,
    "description": null,
    "name": null
}

Solution 7 - Typescript

If you already have a class and you want to create new instance and initialize properties at the same time you can try this

return Object.assign(new Person(), {
    name:"Your Name"
});

Solution 8 - Typescript

interface Person{
    id: number; 
    name: string;
}

let x: Person = {
    id : 0,
    name :"JOHN"
};

alert(x.name);

Solution 9 - Typescript

You can use Record type as well.

{
    category: Record<string, string>;
}

Solution 10 - Typescript

let category = <Category>{ };

This is the way when you don't want to change the definition of either interface or class.

In this way will be generic type of object which isn't dependent on the data type and is also reusable.

Solution 11 - Typescript

You can do :

interface Person{
    id: number; 
    name: string;
}

person : Person = new Person;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAragornView Question on Stackoverflow
Solution 1 - TypescriptIan MacDonaldView Answer on Stackoverflow
Solution 2 - TypescriptVitor M. BarbosaView Answer on Stackoverflow
Solution 3 - TypescriptSerdarView Answer on Stackoverflow
Solution 4 - TypescriptmotoView Answer on Stackoverflow
Solution 5 - TypescriptJake HolzingerView Answer on Stackoverflow
Solution 6 - TypescriptspecView Answer on Stackoverflow
Solution 7 - TypescriptSubhashis PalView Answer on Stackoverflow
Solution 8 - Typescriptnightingale2k1View Answer on Stackoverflow
Solution 9 - TypescriptNikolaevView Answer on Stackoverflow
Solution 10 - TypescriptDave LeeView Answer on Stackoverflow
Solution 11 - Typescriptuser1187282View Answer on Stackoverflow