johni
johni

Reputation: 5568

Typescript polymorphism

Please have a look on this code:

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

class Ge extends Greeter {
    constructor(message: string) {
        super(message);
    }
    greet() {
        return "walla " + super.greet();
    }
}

let greeter = new Ge("world");

console.log(greeter.greet()); // walla Hello, world
console.log((<Greeter> greeter).greet()); // walla Hello, world

I would expect the second log to print Hello, world. Looking at the transpiled Javascript code, I see the exact same command so it's not that a surprise.

The real question is, how do you cast greeter to its extended class?

Upvotes: 8

Views: 12254

Answers (4)

Thomas
Thomas

Reputation: 64

I think you misunderstand casting. It's not a "convert into" but more a "interpret as". It basically gives the compiler a hint, wich type/interface he is dealing with, and therefore wich properties and methods are available. It doesn'n say anything about the implementation of these methods, only their signature (wich types go in, wich type comes out)

Upvotes: 3

user1852503
user1852503

Reputation: 5607

Casting only tells the compiler to treat a variable as if it has a specific type as it's value.

Casting has no effect on the JavaScript code that is outputted. It would sometimes allow the compiler to not emit errors when it thinks you are treating type A as if it was type B. but the JavaScript code has no notion of types.

Your class instance has a property called greet, it hides the property on that objects prototype (the base class greet function). So the function that gets called is always the one lowest on the inheritance line.

You might want to look at the output code, and then apply what you know about prototypical inheritance to understand that code.

Upvotes: 0

ssube
ssube

Reputation: 48267

Methods in JS (and TS) are attached to a prototype which is attached to each instance (something like a virtual method table). When you call a method, the actual function is retrieved from the instance's prototype chain rather than the known type of the object. The closest equivalent I'm aware of are virtual methods in C++.

In code:

let greeter = new Ge('world');
// You expect:
Greeter.prototype.greet.call(greeter);
// JS actually does:
greeter.prototype.greet.call(greeter);

Upvotes: 9

Justin Niessner
Justin Niessner

Reputation: 245419

You already did cast greeter to it's parent class.

An overriden method in a class doesn't change behavior when cast as its parent.

Upvotes: 8

Related Questions