Why constructors
Without a constructor, you create an object and then fill it in one property at a time:
let dog = new Dog();
dog.name = "Rex";
dog.age = 4;
That works, but it is easy to forget a line, and an object exists for a moment in a half-filled state. A constructor is a special method that runs automatically when you write new. It receives the arguments from the parentheses and sets the object up, so a new object comes out ready to use.
Defining a constructor
The constructor is a method named exactly constructor. It has parameters like any method, but no return type and no function keyword:
class Dog {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
Two parts matter here: the field declarations above the constructor, and the assignments inside it.
Declare the fields first
In TypeScript the class has to list its fields. The lines name: string; and age: number; tell the compiler which data a Dog holds and of what type. If you leave them out and only assign inside the constructor, the compiler reports that the property does not exist on Dog:
error TS2339: Property 'name' does not exist on type 'Dog'.
The compiler reports this for each assignment, and it still produces JavaScript that runs. Even so, treat it as an error to fix: without the declarations, the rest of the program loses type checking for name and age.
The this keyword
this refers to the object being built. In this.name = name, the left side is the object's name field and the right side is the constructor's name parameter. They share a name but are different things. A bare name = name would assign the parameter to itself and change nothing in the object.
Calling the constructor
The arguments in new Dog(...) go straight to the constructor, in order:
let rex: Dog = new Dog("Rex", 4);
let luna: Dog = new Dog("Luna", 7);
When each line finishes, the object is complete. rex.name is "Rex", rex.age is 4, and luna has its own values. TypeScript also checks the call itself. new Dog("Max") is reported as Expected 2 arguments, but got 1, and passing "four" for the age would be a type error. These are compile-time checks only. If you ignore the error, the JavaScript still runs, and the missing argument just arrives as undefined:
Dog { name: 'Max', age: undefined }
The exercise
The starter code has an empty Dog class and two console.log lines that read rex and luna. You supply the class body and the two objects.
- Declare the fields
name: stringandage: numberin the class body, one per line. - Write the constructor with parameters of the same names and types, and store each one in the matching field through
this. - Create the dogs below the class:
rexfrom"Rex"and4,lunafrom"Luna"and7.
class Dog {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
let rex: Dog = new Dog("Rex", 4);
let luna: Dog = new Dog("Luna", 7);
console.log(rex.name + " is " + rex.age);
console.log(luna.name + " is " + luna.age);
The output is:
Rex is 4
Luna is 7
The : Dog annotations on rex and luna are optional, since TypeScript infers the type from new Dog(...).
Common mistakes
- Misspelling
constructor. A method named anything else, such asConstructororinit, is an ordinary method. It never runs onnew, and the fields stayundefined. - Forgetting
this.. Inside the constructor,name = namedoes not touch the object. The field remainsundefined. - Swapping the arguments. Arguments match parameters by position, and
new Dog(4, "Rex")is reported as a type error. - Adding a return type or a
returnvalue. A constructor produces the new object by itself. Don't annotate it. - Using the object before
new. The twoconsole.loglines come after the twoletdeclarations. Readingrexearlier fails.
A shorthand to know about
TypeScript has a shortcut called parameter properties. Putting an access modifier on a constructor parameter declares the field and assigns it in one step:
class Dog {
constructor(public name: string, public age: number) {}
}
This produces a Dog with name and age fields, just like the longer version. The lesson uses the explicit form, which shows each step.
Key takeaways
- The constructor is a method named
constructor. It runs automatically onnewand receives the arguments. - Declare each field with its type in the class body, then assign it with
this.field = parameter. - TypeScript checks the number and types of constructor arguments at compile time.
- A constructor has no return type.