user2108287
user2108287

Reputation:

TypeScript mixin constrained to another mixin

I'm using Typescript 2.2's mixins and would like to use the property of one mixin from another.

The docs show that mixins can be constrained to mix into certain classes only...

const WithLocation = <T extends Constructor<Point>>(Base: T) =>
    class extends Base {
        getLocation(): [number, number] {
            return [this.x, this.y];
        }
    }

Is it possible to constrain them to only mix in to classes which contain another mixin?

Upvotes: 4

Views: 495

Answers (1)

David Sherret
David Sherret

Reputation: 106640

Yes, it is possible. Define your other mixin so that it's backed by an interface. For example:

interface Named {
    name: string;
}

function Named<T extends Constructor<{}>>(Base: T) {
    return class extends Base implements Named {
        name: string;
    };
}

You can then use the interface in an intersection type in the Constructor type argument:

const WithLocation = <T extends Constructor<Point & Named>>(Base: T) =>
    class extends Base {
        getLocation(): [number, number] {
            console.log(this.name); // compiles
            return [this.x, this.y];
        }
    };

const NamedPointWithLocation = WithLocation(Named(Point));
const PointerWithLocation = WithLocation(Point); // error, expects argument to be Named

You can see a more complicated example of this being done here that will work when compiling with declaration files.

Upvotes: 6

Related Questions