Am very curious how/why the following trickery is needed in TypeScript. Was playing around with basic class and static constructs, then inheritance, and finally referencing static properties from instance methods. I might not ever implement anything this way... but I did get quite confused why the following works:
class Foo {
msg: string;
static name: string = 'Foo';
static sayHi(): string {
return `hello from ${this.name}`;
}
constructor() {
// this.msg = `I am ${Foo.name}`;
// 2x `I am Foo`
// this.msg = `I am ${this.name}`;
// error TS2339: Property 'name' does not exist on type 'Foo'.
// this.msg = `I am ${this.constructor.name}`;
// error TS2339: Property 'name' does not exist on type 'Function'.
const cls = <typeof Foo>this.constructor;
this.msg = `I am ${cls.name}`;
}
}
class Bar extends Foo {
static name: string = 'Bar';
}
console.log(Foo.sayHi()); // hello from Foo
console.log(Bar.sayHi()); // hello from Bar
console.log((new Foo()).msg); // I am Foo
console.log((new Bar()).msg); // I am Bar
(i'm on tsc 1.8.10, the UPDATE in this answer got it working)
If you jump to @basarat's response, WHY does the type assertion magically make everything work?
Compared to similar python:
class Foo(object):
name = 'Foo'
@classmethod
def sayHi(cls):
return 'hello from {}'.format(cls.name)
def __init__(self):
self.msg = 'I am {}'.format(self.name);
class Bar(Foo):
name = 'Bar'
print(Foo.sayHi()) # hello from Foo
print(Bar.sayHi()) # hello from Bar
print(Foo().msg) # I am Foo
print(Bar().msg) # I am Bar