Jeff
Jeff

Reputation: 141

What's the point of this section of code in Typescript?

I'm reading the handbook for Typescript and I noticed section of code that is (to me) pointless. Can some explain what the purpose of this is?

Taken from the docs:

class Greeter {
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        if (this.greeting) {
            return "Hello, " + this.greeting;
        }
        else {
            return Greeter.standardGreeting;
        }
    }
}

var greeter1: Greeter;
greeter1 = new Greeter();
alert(greeter1.greet());

var greeterMaker: typeof Greeter = Greeter; // This line
greeterMaker.standardGreeting = "Hey there!"; // This line
var greeter2:Greeter = new greeterMaker(); // And this line
alert(greeter2.greet());

So, what the docs say is that var greeterMaker: typeof Greeter = Greeter "will hold the class itself." I'm not entirely sure what that means either

Then it does this:

greeterMaker.standardGreeting = "Hey there!";

// Which does the exact same thing as this:
Greeter.standardGreeting = "Hey there!";

What am I missing here?

Upvotes: 4

Views: 343

Answers (3)

C Snover
C Snover

Reputation: 18766

This part of the documentation seems to be trying to explain the difference between a type of Greeting and a type of typeof Greeting.

To understand these two things, you must first understand that a TypeScript class is syntactic sugar that combines (1) a constructor function and (2) an interface that describes instances generated by that constructor.

So, when you see this:

class Greeter {
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        // ... code ...
    }
}

What you actually are doing is defining something that, written out longhand, looks more like this:

interface Greeter {
  greet(): void;
}

var Greeter: {
  new(): Greeter;
  prototype: Greeter;
  standardGreeting: string;
};

Greeter = function () {};
Greeter.prototype.greet = function () {
  // ...code...
};

In other words, you’ve written an interface Greeter that describes Greeter instances, plus a second anonymous type on a variable Greeter that describes the constructor function. (This works because types exist in a separate, parallel namespace that does not conflict with the variable names in generated code.)

Using the Greeter interface type is obvious enough—just write Greeter—but how does one access this anonymous type attached to the Greeter variable? The answer is the typeof type modifier. Writing typeof Greeter says “use the type of the variable Getter”, which lets us access the anonymous type assigned to the variable Greeter that holds the constructor.

So that is what the documentation is trying to explain. Hopefully this explanation is much clearer and we can now understand this part of the code:

// This creates an alias called `greeterMaker` to the
// Greeter constructor function
// (functions are objects, and objects are always handled
// by-reference in JavaScript)
var greeterMaker: typeof Greeter = Greeter;

// This modifies the `standardGreeting` property of the
// function through the alias
greeterMaker.standardGreeting = "Hey there!";

// This invokes the constructor function through the alias,
// constructing a new instance of a Greeter
var greeter2:Greeter = new greeterMaker(); // And this line

Upvotes: 2

user2197169
user2197169

Reputation: 147

If you run the code, you will see that "Hello, there" should be displayed in an alert box. Followed by "Hey there!".

The static variable cannot be changed in the class Greeter without Creating a new on as a Typeof.

if you try to add line greeter.standardGreeting = "Hey there!";

It will error.

Upvotes: 0

ssube
ssube

Reputation: 48267

This is working within TS' typing system to get a reference to the class, without declaring greeterMaker as holding a class directly (I imagine foo: class is probably not allowed).

In theory, this will work even if the value on the right isn't Greeter but is some other class with similar semantics and the same public static field. It could allow you to dynamically provide a different class and use that, but in this example, isn't particularly helpful.

Upvotes: 1

Related Questions