Feature Request / Proposal: Traits


Traits, as "compile-time" partial classes, would perfectly fit with TS ideology and resolve problems of multiple inheritance/mixins.

Traits in Scala: http://en.wikibooks.org/wiki/Scala/Traits
Traits in PHP: http://php.net/trait

I propose minimal traits similar to PHP implementation.
trait FooTrait {
   // same as class definition, but no constructor allowed, e.g.:
   public foo() {
       return "foo";
   private bar() {
       return "bar";

class Foo {
    import FooTrait; //not insisting on exact keyword and syntax, just smth to start with

    // ...

class Bar {
    // rename methods:
    import FooTrait(foo => tfoo, bar => tbar);

    // and to include another trait, there is another import line:
    // import BarTrait;

    // ...
The code above could be compiled to JS below (can be optimized, just showing the main idea):
var FooTrait = (function () {
    function FooTrait() {
        throw "Cannot instantiate trait FooTrait";
    FooTrait.prototype.foo = function () {
        return "foo";
    FooTrait.prototype.bar = function () {
        return "bar";
    return FooTrait;

var Foo = (function (_super, FooTrait) {
    function Foo() { }
    Foo.prototype.foo = FooTrait.prototype.foo;
    Foo.prototype.bar = FooTrait.prototype.bar;
    return Foo;
})(undefined, FooTrait);

var Bar = (function (_super, FooTrait) {
    function Bar() { }
    Bar.prototype.tfoo = FooTrait.prototype.foo;
    Bar.prototype.tbar = FooTrait.prototype.bar;
    return Bar;
})(undefined, FooTrait);
Unresolved name conflicts should raise a compile time error.


SimoneGianni wrote Jun 11, 2013 at 3:46 PM

Details of the implementation may be discussed, but I do second this. I've been using these kind of techniques almost everywhere possible, including languages that are entirely based on non supporting them like Java (using AspectJ) .

It can be implemented in a number of ways. The prototype chain may be altered to include required traits, with proper ordering in respect to the real super class (there is quite some literature on this). Or it could be implemented as simple syntactical sugar with automatic delegation, where the trait is an interface, indicating a "default implementation", and classes using that trait have implicitly defined methods that delegate to an instance of the default implementation.

EisenbergEffect wrote Aug 31, 2013 at 7:43 PM

This would make me cry for joy.

Jaben wrote Oct 15, 2013 at 12:45 PM

+1 I would also like to see this feature added.