Reputation: 141
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
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
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
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