The Constructor

With fixed initial values, every new monster starts out as a goblin with 30 health, and you have to change its fields after new. It's more practical to say right away what you want: new Monster("Wolf", 25). That's what the constructor is for:

class Monster {
    name: string;
    health: number;

    constructor(name: string, health: number) {
        this.name = name;
        this.health = health;
    }
}

const wolf = new Monster("Wolf", 25);
const troll = new Monster("Troll", 80);
console.log(wolf);
console.log(troll);

This prints:

Monster { name: "Wolf", health: 25 }
Monster { name: "Troll", health: 80 }

The constructor is a special function inside the class, named constructor. You never call it yourself: new calls it every time it creates an object, and the arguments of new Monster("Wolf", 25) go into its parameters. The parameters have types, as in any function, so TypeScript checks the arguments of new: new Monster("Wolf") gives Expected 2 arguments, but got 1. (TS2554), and new Monster(25, "Wolf") is TS2345.

What is this? Inside the constructor, this is the new object that's being created. this.name = name; means: “Set the field name of the new object to the value of the parameter name.” Both sides have the same name, which is usual, but they are two different things: this.name is the field, plain name is the parameter.

So new Monster("Wolf", 25) does this:

  1. It creates a new, empty object of the class Monster.
  2. It sets the fields that have an initial value.
  3. It runs the constructor with this being the new object, so that the constructor can fill in the rest.
  4. It gives you the finished object.

The fields name and health have no initial values now, and that's fine: TypeScript checks that the constructor gives each of them a value. A field can also keep an initial value and not appear in the constructor at all, like level: number = 1;.

Typical mistake: forgetting this. in this.name = name;. Then name = name; only assigns the parameter to itself, and the field stays empty. TypeScript notices:

class Monster {
    name: string;
    health: number;

    constructor(name: string, health: number) {
        name = name;
        this.health = health;
    }
}

TypeScript reports:

main.ts(2,5): error TS2564: Property 'name' has no initializer and is not definitely assigned in the constructor.

A note for later. In other TypeScript code, you'll come across a shorter way of writing this: constructor(public name: string) {} declares the field and sets it in one go. It's called a parameter property, and this site doesn't allow it: you'd get This syntax is not allowed when 'erasableSyntaxOnly' is enabled. (TS1294), the same message as for enum in lesson 5. A parameter property isn't just JavaScript with types: TypeScript has to generate extra code for it, and tools that only remove the types can't do that. So write the fields and this.name = name;, as above.

Instructions

Give Hero a constructor with two parameters, name: string and heroClass: HeroClass, which sets the fields name and heroClass. Remove the initial values of these two fields (level keeps its 1). TypeScript then reports the lines with new Hero(): give them their arguments, new Hero("Kira", "ranger") and new Hero("Bruno", "warrior"), and delete the two lines that changed Bruno afterwards. The program prints the same as before.

Lena the mage joins the party. Create lena with the constructor and print her, using her fields, like this:

Lena the mage, level 1

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

2/9