Reputation: 1295
In the Angular 2 guide Dependency Injection (in the first chapter Why dependency injection?) there are some strange lines of code. They work, but I don't know why. You can also find the running example on https://angular.io/resources/live-examples/dependency-injection/ts/eplnkr.html.
In the file car.ts the class Engine and the class Car are declared as:
export class Engine {
public cylinders = 4;
}
export class Car {
public description = 'DI';
constructor(public engine: Engine, public tires: Tires) { }
...
}
In the file car-creation.ts the class Car is used ...
import { Car, Engine, Tires } from './car';
class Engine2 {
constructor(public cylinders: number) { }
}
export function superCar() {
// Super car with 12 cylinders and Flintstone tires.
let bigCylinders = 12;
let car = new Car(new Engine2(bigCylinders), new Tires());
car.description = 'Super';
return car;
}
It works without warnings or errors by the Typescript compiler.
Strange! Why it is possible to create car with a wrong engine type?
new Engine2(...)
creates an object from class Engine2 which is not derived from class Engine.
Is this behavior a bug or a feature of Typescript?
I would expect the following lines of code in the file car-creation.ts.
class Engine2 extends Engine {
constructor(public cylinders: number) {
super();
}
}
... or ...
class Engine2 extends Engine {
constructor(cylinders: number) {
super();
this.cylinders = cylinders;
}
}
Upvotes: 0
Views: 103
Reputation: 16856
TypeScript uses structural typing instead of nominal typing. You can find more on the topic here. Even though you're writing class
it is not a ... class in the sense of class-inheritance. It's just syntax sugar for creating a Prototype.
class Engine2 {
constructor(public cylinders: number) { }
}
class Engine {
public cylinders = 4;
}
Even though they do not inherit from each other, they a the same on a structural level. Both have a public
member cylinders
that is a number
. While Engine
will always have 4 cylinders, you can init Engine2
with any number of cylinders.
Writing the constructor like constructor(public cylinders: number) {}
is syntax sugar for initializing a public member.
Upvotes: 1