Reputation: 14299
Is there a way to define a "member variable" as an "extension object" instead of a static type (without using an interface)?
Simply something like this pseudocode:
class Foo {
bar -> extends Rectangle;
constructor(barInstance:IRectangle){
this.bar = barInstance;
this.bar.getArea(); //<-- is code completed because interface IRectangle
// no type error
this.bar.someCustomFunction = function() {
}
}
}
instead of
class Foo {
bar: IRectangle;
//or
bar:Rectangle;
}
This way I can add properties not defined on the base class or interface without getting type errors, but also get code completion from the base class. Heh, lazy strict typing?
Upvotes: 1
Views: 4229
Reputation: 2848
Intersection Types
interface IRectangle {
getArea: () => number;
}
class Foo {
bar: IRectangle & { [key: string]: any; };
constructor(barInstance:IRectangle){
this.bar = barInstance;
this.bar.getArea(); //<-- is code completed because interface IRectangle
// no type error
this.bar.someCustomFunction = function() {
}
}
}
Upvotes: 2
Reputation: 164147
I'm not completely sure that I understand you, but if so then something like this:
interface IRectangle {
getArea(): void;
}
class Rectangle implements IRectangle {
getArea(): void {}
someCustomFunction(): void {}
}
class Foo<T extends IRectangle> {
bar: T;
constructor(barInstance: T){
this.bar = barInstance;
this.bar.getArea();
// no type error
if (this.bar instanceof Rectangle) {
(this.bar as any as Rectangle).someCustomFunction = function() {}
}
}
}
Upvotes: 0
Reputation: 4337
Consider a constrained generic type parameter.
interface Base {
prop: number;
}
interface Child extends Base {
thing: string;
}
class Foo<T extends Base> {
bar: T
}
var foo = new Foo<Child>();
foo.bar.thing; // now permitted by the type checker
Upvotes: 0