Getting Rid Of The Type Assertion
If you follow the Liskov substitution principle, you don't need the type assertion.
Code Example 1 - Substitutable Objects...
module Test {
export class Base {
publicVar: string = 'base';
static getSomething() : Base {
//... read on...
}
}
export class Foo extends Base {
publicVar:string = 'getThis!';
}
}
// No <Foo> type assertion needed
var foo: Test.Foo = Test.Foo.getSomething();
alert(foo.publicVar);
Alternatively, you could create an interface
that tells you the object returned will have a publicVar property and return that...
Code Example 2 - Interface
module Test {
export interface IPublicVarable {
publicVar: string;
}
export class Base {
static getSomething() : IPublicVarable {
//... read on...
}
}
export class Foo extends Base {
publicVar:string = 'getThis!';
}
}
// No <Foo> type assertion needed
var foo: Test.IPublicVarable = Test.Foo.getSomething();
alert(foo.publicVar);
Getting the Actual Type
This doesn't solve one other issue you have though - var type = typeof this;
isn't going to give you what you expect at runtime. It is going to give you Function
not Foo
.
To get a type name, you really need to work with an instance (if you use Test.Foo
the type name is Function
once again - which does you no good), so here is an imperfect example using two different subclasses that both satisfy the interface, based on my Obtaining a Class Name at Runtime example:
module Test {
export class Describer {
static getName(inputClass) {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((<any> inputClass).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
}
static getInstanceOf(inputClass) : Test.IPublicVarable {
var name = Describer.getName(inputClass);
return new Test[name]();
}
}
export interface IPublicVarable {
publicVar: string;
}
export class Base {
}
export class Foo extends Base {
publicVar:string = 'foo class';
}
export class Bar extends Base {
publicVar:string = 'bar class';
}
}
var a: Test.Base = new Test.Foo();
var x: Test.IPublicVarable = Test.Describer.getInstanceOf(a);
alert(x.publicVar);
var b: Test.Base = new Test.Bar();
var y: Test.IPublicVarable = Test.Describer.getInstanceOf(b);
alert(y.publicVar);