All Projects → michaelolof → typescript-mix

michaelolof / typescript-mix

Licence: other
A tweaked implementation of TypeScript's default applyMixins(...) idea using ES7 decorators

Programming Languages

typescript
32286 projects
shell
77523 projects

Projects that are alternatives of or similar to typescript-mix

Web Portfolio
Personal portfolio website made with the React
Stars: ✭ 207 (+155.56%)
Mutual labels:  mixins
Grimoire-legacy
General-purpose Mixin loader framework, which allows to properly implement mixins on 1.7.10/1.12.2 versions of Minecraft. For updated version check out https://github.com/Aizistral-Studios/Grimoire
Stars: ✭ 27 (-66.67%)
Mutual labels:  mixins
plazar-js
Modular framework built with enterprise in mind - http://www.plazarjs.com
Stars: ✭ 25 (-69.14%)
Mutual labels:  mixins
Pug Bootstrap
Bootstrap framework written completely using mixins in Pug
Stars: ✭ 212 (+161.73%)
Mutual labels:  mixins
ignite
A Mixin and Access Widener mod loader for Spigot/Paper
Stars: ✭ 115 (+41.98%)
Mutual labels:  mixins
go-traits
A concept package that helps implement mixin behavior using embedded structs and hook interfaces.
Stars: ✭ 21 (-74.07%)
Mutual labels:  mixins
Uniflow Polymer
UniFlow for Polymer
Stars: ✭ 168 (+107.41%)
Mutual labels:  mixins
Cometary
Roslyn extensions, with a touch of meta-programming.
Stars: ✭ 31 (-61.73%)
Mutual labels:  mixins
tale-pug
Tale Pug is the popular JavaScript Template Engine Pug, formerly Jade, for PHP!
Stars: ✭ 32 (-60.49%)
Mutual labels:  mixins
rupture-sass
Better media queries mixins library for SASS
Stars: ✭ 47 (-41.98%)
Mutual labels:  mixins
Hyperium
Hyperium, Free Minecraft client with HUDs and Popular mods
Stars: ✭ 217 (+167.9%)
Mutual labels:  mixins
media-blender
Easy and predictable SASS/SCSS media queries
Stars: ✭ 26 (-67.9%)
Mutual labels:  mixins
Sledgehammer
Smashes the stupid out of the client & server.
Stars: ✭ 13 (-83.95%)
Mutual labels:  mixins
Styled Components Spacing
Responsive margin and padding components for styled-components 💅.
Stars: ✭ 209 (+158.02%)
Mutual labels:  mixins
less-mix
LESS-Mix - is a functional, powerful and convenient library LESS-mixins.
Stars: ✭ 22 (-72.84%)
Mutual labels:  mixins
Browser Hack Sass Mixins
Browser hack sass mixin - Apply your SCSS to a specific browser - CSS hacks for: IE, Chrome, Firefox, Edge, Opera
Stars: ✭ 170 (+109.88%)
Mutual labels:  mixins
NCop
Composite-aspect oriented framework for .NET
Stars: ✭ 30 (-62.96%)
Mutual labels:  mixins
chameleon-sdk
Chameleon Software Development Kit
Stars: ✭ 12 (-85.19%)
Mutual labels:  mixins
rainbowify
Fabric mod for rainbow and blur backgrounds in minecraft guis
Stars: ✭ 18 (-77.78%)
Mutual labels:  mixins
sass-boilerplate
A collection of common use Sass stylesheets, mixins and functions.
Stars: ✭ 60 (-25.93%)
Mutual labels:  mixins

TypeScript Mix

A tweaked implementation of TypeScript's default applyMixins(...) idea using ES7 decorators.

Breaking Changes from Version 3.0.0 upwards

  • New decorator @delegate introduced
  • Changes made in how multiple mixins implementing the same method are mixed

See Breaking Changes Explained

Dependencies

  • TypeScript
  • ES7 Decorators

Installation

npm install --save typescript-mix

Features

Goals

  • Ensure programming to an interface and not just only multiple implementations.

  • Create simple mixins that implement that interface

  • Provide an intuitive and readable way of using such mixins in a concrete class.

Why I wrote yet another Mixin Library.

The mixin pattern is somewhat a popular pattern amongst JavaScript/TypeScript devs as it gives the power of "mixin in" additional functionality to a class. The official way of using mixins as declared by Microsoft in TypeScript can be really verbose to downright unreadable.

How to use

The 'use' decorator

Program to an interface.

interface Buyer {
  price: number
  buy(): void
  negotiate(): void
}

Create a reusable implementation for that interface and that interface alone (Mixin)

const Buyer: Buyer = {
  price: undefined,
  buy() {
    console.log("buying items at #", this.price );
  },
  negotitate(price: number) {
    console.log("currently negotiating...");
    this.price = price;
  },
}

Define another mixin this time using a Class declaration.

class Transportable {
  distance:number;
  transport() {
    console.log(`moved ${this.distance}km.`);
  }
}

Define a concrete class that utilizes the defined mixins.

import use from "typescript-mix";

class Shopperholic {
  @use( Buyer, Transportable ) this
  
  price = 2000;
  distance = 140;
}

const shopper = new Shopperholic();
shopper.buy() // buying items at #2000
shopper.negotiate(500) // currently negotiating...
shopper.price // 500
shopper.transport() // moved 140km

What about intellisense support?

We trick typescript by using the inbuilt interface inheritance and declaration merging ability.

interface Shopperholic extends Buyer, Transportable {}

class Shopperholic {
  @use( Buyer, Transportable ) this
  
  price = 2000;
  distance = 140;
}

The 'delegate' decorator

The delegate decorator is useful when we want specific functionality mixed into the client.

class OtherClass {
  simpleMethod() {
    console.log("This method has no dependencies");
  }
}

function workItOut() {
  console.log("I am working it out.")
}

class MyClass {
  @delegate( OtherClass.prototype.simpleMethod )
  simpleMethod:() => void

  @delegate( workItOut ) workItOut:() => void
}

const cls = new MyClass();
cls.simpleMethod() // This method has no dependencies
cls.workItOut() // I am working it out

Things to note about this library?

  • using the 'use' decorator mutates the class prototype. This doesn't depend on inheritance (But if you use mixins correctly, you should be fine)

  • mixins don't override already declared methods or fields in the concrete class using them.

  • Mixins take precedence over a super class. i.e. they would override any field or method from a super class with the same name.

  • instance variables/fields/properties can be declared or even initialized in your mixins. This is necessary if you're defining methods that depend on object or class properties but these properties won't be mixed-in to the base class so you have to redefine those properties in the base class using the mixin.

Advantages

  • The Library is non-obtrusive. Inheritance still works, (multiple inheritance still works ('Real Mixins Style')).

Breaking Changes Explained

The delegate decorator

The addition of the delegate decorator now means module is imported as:

import { use, delegate } from "typescript-mix"

Multiple Mixins with the same method.

Consider the following piece of code. alt text

Cleint One uses two mixins that contain the same method mixIt(). How do we resolve this? Which method gets picked?. One advantage of extending interfaces as we've defined above is that we're essentially telling TypeScript to mix-in the two mixin interfaces into the ClientOne interface. So how does TypeScript resolve this?

alt text

Notice that TypeScript's intellisense calls MixinOne.mixIt() method. Therefore to be consistent with TypeScript and avoid confusion the '@use' decorator also implements MixinOne.mixIt() method.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].