https://github.com/hasnainroopawalla/ts-mxn
A lightweight TypeScript Mixin framework
https://github.com/hasnainroopawalla/ts-mxn
generics mixin mixins oop runtime typescript
Last synced: 7 months ago
JSON representation
A lightweight TypeScript Mixin framework
- Host: GitHub
- URL: https://github.com/hasnainroopawalla/ts-mxn
- Owner: hasnainroopawalla
- License: mit
- Created: 2024-08-24T07:54:57.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-01-25T07:17:59.000Z (9 months ago)
- Last Synced: 2025-03-16T09:25:25.526Z (8 months ago)
- Topics: generics, mixin, mixins, oop, runtime, typescript
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/ts-mxn
- Size: 25.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ts-mxn
[](https://bundlephobia.com/result?p=ts-mxn)
## Overview
`ts-mxn` is a lightweight TypeScript Mixin framework. The [Mixin pattern](https://www.patterns.dev/vanilla/mixin-pattern/) is meant to add reusable functionality to objects without any class inheritance.
### Features
- Intuitive way to create Mixins for easy integration into existing systems.
- Strong type-safety during compilation, along with runtime safety while creating and initializing the Mixins.
- Provides inter-class reusability of attributes (props/methods) by passing the _mixed_ object to the initializer (constructor).
## 🏁 Getting started
```
$ npm install ts-mxn
// OR
$ yarn add ts-mxn
```
## 💡 Quick start
A `Bank` system where the core functionality is _mixed_ in from various existing classes like `Amount` and `Deposit`:
```typescript
import { BaseMixin } from "ts-mxn";
type IAmount = {
amount: number;
setAmount: (newAmount: number) => void;
};
// Basic class to manage the amount
class Amount implements IAmount {
public amount: number = 1000;
constructor(private readonly bank: IBank) {}
public setAmount(newAmount: number): void {
this.amount = newAmount;
}
}
// Define the Amount Mixin
class AmountMixin extends BaseMixin {
constructor() {
super({
// Specify the methods and props to be be mixed
methods: ["setAmount"],
props: ["amount"],
initMixin: bank => new Amount(bank),
});
}
}
```
```typescript
import { BaseMixin } from "ts-mxn";
type IDeposit = {
deposit: (amount: number) => void;
};
// Basic class to deposit money into the account
class Deposit implements IDeposit {
constructor(private readonly bank: IBank) {}
public deposit(depositAmount: number): void {
this.bank.setAmount(this.bank.amount + depositAmount);
}
}
// Define the Deposit Mixin
class DepositMixin extends BaseMixin {
constructor() {
super({
// Specify the methods and props to be be mixed
methods: ["deposit"],
props: [],
initMixin: bank => new Deposit(bank),
});
}
}
```
Define the `IBank` interface to represent the Mixed object based on the above Mixins:
```typescript
type IBank = IAmount & IDeposit;
```
Create the mixed `bank` object using an input list of Mixin implementations:
```typescript
import { mix } from "ts-mxn";
const bank = mix({
mixins: [new AmountMixin(), new DepositMixin()],
});
// Complete type-safety for the mixed object
console.log(bank.amount); // 1000
bank.deposit(500);
console.log(bank.amount); // 500
bank.setAmount(2000);
console.log(bank.amount); // 2000
```
Runtime safety is guaranteed in the following scenarios:
- Attempting to bind a method as a prop and vice versa.
- Attempting to bind a prop/method that already exists on the object.
## ✏️ Contributing
- Post any issues and suggestions on the GitHub [issues](https://github.com/hasnainroopawalla/ts-mxn/issues) page.
- To contribute, fork the project and then create a pull request back to `main`.