@lifaon/traits

Traits for javascript: mix your classes with ease

Usage no npm install needed!

<script type="module">
  import lifaonTraits from 'https://cdn.skypack.dev/@lifaon/traits';
</script>

README

npm (scoped) npm NPM npm type definitions

🏗️ Traits

A trait is a set of methods that can used to extend the functionality of a class, and is particularly useful in multi-inheritance.

A trait doesn't have any internal state, it only provides some typed and constrained methods, and relies on the provided this to carry the data. It's some kind of framework for classes, or abstract classes with super-powers.

A trait comes with an implementation, which is the implementation of a trait for a specific data structure.

🛠️ Example

// add.trait.ts

@Trait()
export abstract class AddTrait<GSelf, GValue = GSelf, GReturn = GSelf> {
  abstract add(this: GSelf, value: GValue): GReturn;
}
Click to expand
// number-add.implementation.ts

@Impl()
export class NumberAddImplementation<GSelf extends INumber> extends AddTrait<GSelf, NumberLike, INumber> {
  add(this: GSelf, value: NumberLike): INumber {
    return new NumberLike(this.value + value.value);
  }
}
// number.class.ts

export interface INumberImplementations extends
  NumberAddImplementation<INumber>,
  NumberSubtractImplementation<INumber>
{}

export const NumberImplementations = [
  NumberAddImplementation,
  NumberSubtractImplementation,
];

export interface INumberImplementationsConstructor {
  new(): INumberImplementations;
}

export interface INumber extends INumberImplementations {
  value: number;
}

const NumberImplementationsConstructor = assembleTraitImplementations<INumberImplementationsConstructor>(NumberImplementations);

export class NumberLike extends NumberImplementationsConstructor implements INumber {
  value: number;

  constructor(value: number) {
    super();
    this.value = value;
  }
}

📦 Installation

yarn add @lifaon/traits
# or
npm install @lifaon/traits --save

This library supports:

  • common-js (require): transpiled as es5, with .cjs extension, useful for old nodejs versions
  • module (esm import): transpiled as esnext, with .mjs extension (requires node resolution for external packages)

In a node environment the library works immediately (no extra tooling required), however, in a browser environment, you'll need to resolve external imports thought a bundler like snowpack, rollup, webpack, etc... or directly using skypack: https://cdn.skypack.dev/@lifaon/traits

📕 Documentation