What is the best practice for creating model objects in Angular / TypeScript:
Should I use type annotation with object notation (objects are plain instances of
Object
)? E.g.let m: MyModel = { name: 'foo' }
Should I use the
new
operator (objects are instances of the respective prototype)?Should these two approaches be mixed up and used situationally? (E.g plain objects, when receiving a response from the
HttpClient
, butnew MyModel('foobar')
for convenience to create instances by passing properties as constructor arguments)
Background of this question
I'm new to TypeScript and like many other developers I come from popular object oriented languages like Java.
A core concept I understood is that type annotations in TypeScript don't play a role at runtime. They are important for the compiler and for your editor's auto completion. Basically it's ECMAScript with the addition of compile time type checks.
At the time I didn't know this and expected TypeScript to be some kind of "client side Java", I found this Angular bug report: https://github.com/angular/angular/issues/20770
People (who don't understand TypeScript's type concept) complain about the HttpClient
not converting the returned plain object to their model class type. Other people are defending this behavior and point out that there are no runtime types in JavaScript.
And here arises my problem: In fact there ARE runtime types in JavaScript. You can create instances of prototypes with the new
operator and even check their constructor with the instanceof
operator.
In TypeScript you have two ways for creating an instance:
1) Use the object notation (as they show in the Angular tutorial):
hero: Hero = {
id: 1,
name: 'Windstorm'
};
2) Use the new
-operator:
hero: Hero = new Hero();
At the moment I'm working on a project where these two options are mixed up. I.e. model objects of the same type are instances of Object
in some cases and instances of Hero
in other cases.
I expect this leading to problems later, because the constructor is only called in the latter case.
My idea for a rule / best practice was to define all model instances as plain objects and to use the constructor for services, components etc. that are created by dependency injection. As a result I wouldn't use the new
operator at all.
However I'm not sure if this is a good idea and I couldn't find a best practice recommendation about it.
EDIT
Important note for close voters: I'm not looking for your personal opionion here. I'm rather looking for some kind of officially documented Angular best practice, as I think it's a core design decision that has to be made right from the project start and these approaches should not be mixed up randomly without a specific reason. Maybe the answer is just a simple "There is no official recommendation which decision to make".