Reputation: 5289
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?
Upvotes: 135
Views: 307709
Reputation: 1695
Other ways to initialize an object would be by using pipe (|)
to define multiple types which is best if you expect the object to be filled out in the future say by a callback or rest call.
But you may have to handle the cases of nullability here else you will end up with null ref exception.
Here is a sample usage:
export class MyClass{
myObject : MyObject | null = null;
}
Note : myObject field is expected by compiler to be initialized by values or null
Another way is to use the undefined fields, this way the compiler won't expect an initializer
export class MyClass{
rates : MyObject | undefined; //compiler doesn't expect it to be initalized
}
Upvotes: 0
Reputation: 524
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.
Upvotes: 1
Reputation: 1237
You can do :
interface Person{
id: number;
name: string;
}
person : Person = new Person;
Upvotes: -5
Reputation: 940
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.
Upvotes: 26
Reputation: 1
You can use Record
type as well.
{
category: Record<string, string>;
}
Upvotes: 0
Reputation: 3646
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()
Upvotes: 59
Reputation: 149
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"
});
Upvotes: 3
Reputation: 14030
There are a number of ways to solve this problem, depending on your desired result.
interface
to a class
export class Category {
name: string;
description: string;
}
const category: Category = new Category();
interface
as a class
export class CategoryObject implements Category {
}
const category: Category = new CategoryObject();
interface
const category: Category = {
name: 'My Category',
description: 'My Description',
};
export interface Category {
name?: string;
description?: string;
}
const category: Category = {};
Partial<T>
export interface Category {
name: string;
description: string;
}
const category: Partial<Category> = {};
Upvotes: 235
Reputation: 449
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
}
Upvotes: 7
Reputation: 10335
interface Person{
id: number;
name: string;
}
let x: Person = {
id : 0,
name :"JOHN"
};
alert(x.name);
Upvotes: 1
Reputation: 6063
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;
Upvotes: 6
Reputation: 797
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.
Upvotes: 25