<p dir="auto">The type system does a great job at mirroring most type patterns in JS, all except mixins/traits, anything that decorates types - which unfortunately is very common in JS.</p>
<p dir="auto">Without it the type system remains incomplete - that is, we're still one step short of being able to describe JavaScript mixin type patterns.</p>
<p dir="auto"><a href="https://typescript.codeplex.com/wikipage?title=Mixins%20in%20TypeScript" rel="nofollow">Duplication and interfaces</a> are not the answer, because this does not reflect what's actually happening in JavaScript - e.g. not duplication, but type decoration of sorts. Not sure if I'm using the correct terminology here.</p>
<p dir="auto"><a href="https://github.com/muut/riotjs/blob/master/lib/observable.js">This small library</a> is an example of a real-world decorator - duplicating all of it's method declarations in every single model type in a view-model hierarchy would be extremely impractical.</p>
<p dir="auto">The following is a simplified example:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class User {
    public name: string;
}

interface Events {
    on(event: string, callback: {():void});
    // other methods here...
}

function addEvents&lt;T&gt;(object: T): T {
    // decorate the object:
    object['on'] = function() {
        // ...
    }
    return &lt;T&gt; {};
}

var user = addEvents(new User());"><pre class="notranslate"><code class="notranslate">class User {
    public name: string;
}

interface Events {
    on(event: string, callback: {():void});
    // other methods here...
}

function addEvents&lt;T&gt;(object: T): T {
    // decorate the object:
    object['on'] = function() {
        // ...
    }
    return &lt;T&gt; {};
}

var user = addEvents(new User());
</code></pre></div>
<p dir="auto">The drawback here is you have to choose which is more important - that <code class="notranslate">User</code> is still a <code class="notranslate">User</code> after being decorated by <code class="notranslate">addEvents()</code>, or that it is now also <code class="notranslate">Events</code>. There is no direct way to document this type pattern - your only option currently is to document the shape of the resulting type fully, duplicating all the member declarations contributed by the decorator.</p>
<p dir="auto">I propose syntax along the lines of the following, to support type alternatives:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function addEvents&lt;T&gt;(object: T): T|Events {
    // decorate the object:
    object['on'] = function() {
        // ...
    }
    return &lt;T|Events&gt; {};
}

var user = addEvents(new User());"><pre class="notranslate"><code class="notranslate">function addEvents&lt;T&gt;(object: T): T|Events {
    // decorate the object:
    object['on'] = function() {
        // ...
    }
    return &lt;T|Events&gt; {};
}

var user = addEvents(new User());
</code></pre></div>
<p dir="auto">The return type of the call is now <code class="notranslate">User|Events</code> which is a distinct composite type composed members of <code class="notranslate">User</code> and <code class="notranslate">Events</code>.</p>
<p dir="auto">The resulting composite type extends <code class="notranslate">User</code> and implements <code class="notranslate">Events</code>, and should pass type-checks for both.</p>
<p dir="auto">This should facilitate type-safe traits/mixins and probably other arbitrary type-patterns possible in JS.</p>
<p dir="auto">Static type-hints with composite types are implemented in this way in e.g. PhpStorm using php-doc annotations, and it works well.</p>
<p dir="auto">I think this may be a simpler and more flexible way to support mixins/traits, without explicitly adding support for those patterns specifically.</p>
<p dir="auto">Thoughts?</p>
<p dir="auto">It would simplify a lot of use cases if we could override relational, equality, additive, and Multiplicative operators.</p>
<p dir="auto">My initial thoughts on how this would work is that functions would replace the operators with functions when compiling to JavaScript.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class MyClass {
    constructor() {
    }

    public Operator &gt; (value: any):boolean {
        // compare value
    }
}

var myClass = new MyClass();

if(myClass &gt; otherValue){
    // Do stuff
}"><pre class="notranslate"><code class="notranslate">class MyClass {
    constructor() {
    }

    public Operator &gt; (value: any):boolean {
        // compare value
    }
}

var myClass = new MyClass();

if(myClass &gt; otherValue){
    // Do stuff
}
</code></pre></div>
<p dir="auto">Becomes:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var MyClass = (function () {
    function MyClass() {
    }
    MyClass.prototype.greaterThan = function (value) {
        // compare value
    };
    return MyClass;
})();
var myClass = new MyClass();
if (myClass.greaterThan(otherValue) {
    // do Stuff
}"><pre class="notranslate"><code class="notranslate">var MyClass = (function () {
    function MyClass() {
    }
    MyClass.prototype.greaterThan = function (value) {
        // compare value
    };
    return MyClass;
})();
var myClass = new MyClass();
if (myClass.greaterThan(otherValue) {
    // do Stuff
}
</code></pre></div>