FlavorScape
FlavorScape

Reputation: 14299

how to declare member variable as extended type in TypeScript?

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

Answers (3)

Rodris
Rodris

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

Nitzan Tomer
Nitzan Tomer

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() {}
        }
    }
}

(code in playground)

Upvotes: 0

Rikki Gibson
Rikki Gibson

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

Related Questions