@ayonli/jsext
Version:
A JavaScript extension package for building strong and modern applications.
46 lines (45 loc) • 1.43 kB
TypeScript
/**
* Declares a class that combines all methods from the base classes.
* @module
*/
import type { Constructor } from "./types.ts";
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
/**
* Creates a class that combines all methods from the given base class and mixin
* classes.
*
* @example
* ```ts
* import mixin from "@ayonli/jsext/mixin";
* import { isSubclassOf } from "@ayonli/jsext/class";
*
* class Log {
* log(text: string) {
* console.log(text);
* }
* }
*
* class View {
* display(data: Record<string, any>[]) {
* console.table(data);
* }
* }
*
* class Controller extends mixin(View, Log) {
* constructor(readonly topic: string) {
* super();
* }
* }
*
* const ctrl = new Controller("foo");
* ctrl.log("something is happening");
* ctrl.display([{ topic: ctrl.topic, content: "something is happening" }]);
*
* console.assert(isSubclassOf(Controller, View));
* console.assert(!isSubclassOf(Controller, Log));
* ```
*/
export default function mixin<T extends Constructor<any>, M extends any[]>(base: T, ...mixins: {
[X in keyof M]: Constructor<M[X]>;
}): T & Constructor<UnionToIntersection<FlatArray<M, 1>>>;
export default function mixin<T extends Constructor<any>, M extends any[]>(base: T, ...mixins: M): T & Constructor<UnionToIntersection<FlatArray<M, 1>>>;