TypeScript Mixin Utility
ts-mixer is a lightweight TypeScript library designed to provide robust mixin functionality, addressing common pitfalls found in other mixin implementations. It enables developers to compose classes through a multiple-inheritance-like mechanism, supporting complex scenarios such as mixing classes that extend other classes, abstract classes (TypeScript >= 4.2), and generic classes (with specific caveats). The current stable version is 6.0.4. The project appears to follow a release cadence driven by feature development and bug fixes, as indicated by its conventional commits usage. Key differentiators include its ability to support static, protected, and private properties, as well as a more resilient approach to constructor complexities and decorator usage compared to simple function-returning-class solutions. It offers different mixing strategies, including ES6 proxies and hard copies, providing flexibility for various use cases.
Common errors
-
Base class expressions cannot reference class type parameters.
cause Attempting to mix generic classes using the standard `Mixin` function or without proper declaration merging.fixUse the `mix` function provided by `ts-mixer` in conjunction with TypeScript's declaration merging to properly handle generic class mixing. -
TypeError: Right-hand side of 'instanceof' is not an object
cause Trying to use `instanceof` with a class that was created using `ts-mixer`, which modifies the prototype chain in a way incompatible with native `instanceof`.fixReplace `instanceof` checks with `ts-mixer`'s `hasMixin(instance, MixinClass)` utility function.
Warnings
- gotcha Direct `instanceof` checks will not work correctly with classes mixed using `ts-mixer`. The library provides a `hasMixin` function as a replacement.
- gotcha When mixing generic classes, a more cumbersome notation using the `mix` function and TypeScript's declaration merging is required due to TypeScript limitations.
- gotcha Applying decorators to mixed classes also requires a specific, more verbose notation. Standard decorator application might not work as expected.
- gotcha ES6 constructors cannot be called without `new`, which prevents `ts-mixer` from reliably passing the proper `this` context to base class constructors. This can affect how constructor logic behaves.
- gotcha Certain features like `@decorator` and `hasMixin` rely on ES6 `Map`. If targeting environments older than ES6, you must provide a polyfill for `Map`.
Install
-
npm install ts-mixer -
yarn add ts-mixer -
pnpm add ts-mixer
Imports
- Mixin
const Mixin = require('ts-mixer').Mixin;import { Mixin } from 'ts-mixer'; - mix
import mix from 'ts-mixer';
import { mix } from 'ts-mixer'; - hasMixin
someInstance instanceof SomeMixin;
import { hasMixin } from 'ts-mixer';
Quickstart
import { Mixin } from 'ts-mixer';
class Foo {
protected makeFoo() {
return 'foo';
}
}
class Bar {
protected makeBar() {
return 'bar';
}
}
class FooBar extends Mixin(Foo, Bar) {
public makeFooBar() {
return this.makeFoo() + this.makeBar();
}
}
const fooBar = new FooBar();
console.log(fooBar.makeFooBar());