Reputation:
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
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