Jonathan Kuhl
Jonathan Kuhl

Reputation: 709

'new' vs implicit typing

I'm taking an Udemy course to learn Angular. In this course, we're making an app that displays recipes and lets you add items from a recipe to a shopping list. I've created a model to describe an ingredient in TypeScript and I've gone ahead and placed them in an array.

The code looks like this:

Here's the model (short and simple)

export class Ingredient {
    constructor(public name: string, public amt: number) {}
}

And here's where it's used in the component:

export class ShoppingListComponent implements OnInit {
  ingredients: Ingredient[] = [
    { name: 'Apples', amt: 5 },
    { name: 'Tomatos', amt: 3 },
  ];

My question is this: The instructor declares the objects in the array using new, like so: new Ingredient('Apples', 5) but what I'm wondering is, is the new keyword necessary? The ingredients array is explicitly typed to Ingredient, so wouldn't any object put in the array be forced to conform to the Ingredient class? Either way the data appears the same on my app when i launch it. And I know the typing works, because if I throw { foo: 'bar' } into the array, webpack refuses to compile.

Is there a difference between calling the constructor with new and with writing out the objects the way I did?

Upvotes: 1

Views: 48

Answers (1)

DeborahK
DeborahK

Reputation: 60568

As Jon mentioned, TypeScript uses structural typing. So what you have done "looks" like an ingredient, but is really not an instance of the class.

If you do something, such as add a method or a getter/setter to the class, your code will break.

For example, try adding a method to your Ingredient class:

export class Ingredient {
    constructor(public name: string, public amt: number) {}

    doubleAmount() {
      return this.amt * 2;
    }
}

You will see that your array then generates a typing error.

It won't generate an error if you do your declaration like this:

ingredients: Ingredient[] = [
  new Ingredient('Apples', 5),
  new Ingredient('Tomatoes', 3),
];

So even though your objects "match" the Ingredient class definition and will be treated as an Ingredient by TS (as long as they continue to match), they are not instances of the Ingredient class.

Make sense?

Upvotes: 2

Related Questions