Generalization in Mixin Definitions
At Geastack Community, we are developing @geastack-community/utils, a package that defines common definitions for creating mixins. This package provides useful functions and definitions for creating mixins and performing various other tasks. On this page, let’s migrate some of the definitions we covered on the previous two pages to those predefined in this library.
First, install the package:
npm install @geastack-community/utils
In this section, we will use the definitions provided here.
export type Constructor<T = any> = new (...args: any[]) => T;
export type AnyConstructor = Constructor;
export type StoreConstructor<T = Store> = Constructor<T>;
export type ComponentConstructor<T = Component> = Constructor<T>;
export type MixinConstructor<
TBase extends AnyConstructor,
Mixin
> = new (...args: ConstructorParameters<TBase>) => InstanceType<TBase> & Mixin;
export interface Disposable {
dispose(): void;
}
These are the five basic constructors and an interface for creating mixins that do not cause memory leaks.
The four constructor types, excluding MixinConstructor, are all instances of Constructor with a type passed to its generics. As for AnyConstructor, it is simply an alias for Constructor.
Now, let's rewrite the code from How to Write Mixin Functions using this library.
It should look like this:
import { Component, Store } from '@geajs/core'
import { ComponentConstructor, MixinConstructor, Disposable } from '@geastack-community/utils'
// You do not need to define a `Constructor`.
// By inheriting from `Disposable`, the type definition prevents developers from forgetting to implement cleanup functionality.
export interface XxxMixin extends Disposable {
xxxProperty: string
doSomething(): void
}
export function withXxx<TBase extends ComponentConstructor>(Base: TBase) {
const Derived = class extends Base implements XxxMixin {
xxxProperty = 'xxxProperty is a property.'
constructor(...args: any[]) {
super(...args)
}
doSomething() {
console.log('Hello World! ', this.xxxProperty)
}
dispose() {
if (typeof super.dispose === 'function') super.dispose();
}
}
return Derived as unknown as TBase & MixinConstructor<TBase, XxxMixin>
}
You can also use StoreConstructor or AnyConstructor when creating mixins for Store or plain classes.