Issue 1:
Hello TypeScripters.

I might be opening a can of worms which might bring an age of darkness upon us (but see PS). Anyway, I've done an attempt to add language support for mixins.

For the user, it is similar to the extends or implements keywords, and thus goes by mixes. The semantic intent of the keyword is that a Mixture is NOT a derived class of its Mixins, it just copies their static and dynamic properties.

Several mixins can be supplied, the order determines which property will finally be mixed (newer definitions shadow previous definitions).

What this does is roughly equivalent to http://www.typescriptlang.org/Handbook#mixins, except there is no need to copy attributes manually, so mixins become more manageable - hopefully.

class Base {
say(hello:string) {
console.log(hello);
}
}

class Mixin1 {
something : string = "Couac couac";

fn1() {
console.log(this.something);
}
}

class Mixin2 {
something : string = "shadowing you, little duck!";

fn2() {
console.log("The dragon is", this.something);
}
}

/* Only mixes one mixin */
class SimpleMixture mixes Mixin1 {

}

/* Mixes several mixins, property definitions in newer mixins (from left
to right) shadow those from previous mixins AND those in the mixture
class itself, including inherited ones. */
class MultiMixture extends Base mixes Mixin1, Mixin2 {

}

var sm1 = new SimpleMixture();
sm1.fn1();

var sm2 = new MultiMixture();
sm2.fn1();
sm2.fn2();

console.log( sm1 instanceof Base );
console.log( sm1 instanceof Mixin1 );
console.log( sm2 instanceof Base );
console.log( sm2 instanceof Mixin2 );

Which emits

var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var __applyMixins = this.__applyMixins || function (mixtureTarget) {
for(var a=1; a<arguments.length; ++a) {
var mixin = arguments[a];
Object.getOwnPropertyNames(mixin.prototype).forEach( function(name) {
mixtureTarget.prototype[name] = mixin.prototype[name];
})
};
};
var Base = (function () {
function Base() {
}
Base.prototype.say = function (hello) {
console.log(hello);
};
return Base;
})();
var Mixin1 = (function () {
function Mixin1() {
this.something = "Couac couac";
}
Mixin1.prototype.fn1 = function () {
console.log(this.something);
};
return Mixin1;
})();
var Mixin2 = (function () {
function Mixin2() {
this.something = "shadowing you, little duck!";
}
Mixin2.prototype.fn2 = function () {
console.log("The dragon is", this.something);
};
return Mixin2;
})();
/* Only mixes one mixin */
var SimpleMixture = (function () {
function SimpleMixture() {
Mixin1.apply(this) ;
}
__applyMixins(/*mixtureTarget*/ SimpleMixture, Mixin1);
return SimpleMixture;
})();
/* Mixes several mixins, property definitions in newer mixins (from left
to right) shadow those from previous mixins AND those in the mixture
class itself, including inherited ones. */
var MultiMixture = (function (_super) {
__extends(MultiMixture, _super);
function MultiMixture() {
_super.apply(this, arguments);
Mixin1.apply(this) ;
Mixin2.apply(this) ;
}
__applyMixins(/*mixtureTarget*/ MultiMixture, Mixin1, Mixin2);
return MultiMixture;
})(Base);
var sm1 = new SimpleMixture();
sm1.fn1();
var sm2 = new MultiMixture();
sm2.fn1();
sm2.fn2();
console.log(sm1 instanceof Base);
console.log(sm1 instanceof Mixin1);
console.log(sm2 instanceof Base);
console.log(sm2 instanceof Mixin2);

and outputs

>>> Couac couac
>>> shadowing you, little duck!
>>> The dragon is shadowing you, little duck!
>>> false
>>> false
>>> true
>>> false

At this point it seems to work with target ES<6 with quite some limitations (the user can't pass arguments to the mixin constructors). Type checking seems to be working (although I could not make Eclipse or Emacs behave with the new keyword). But be warned Very early experimental preview code from a bad JS programmer who knew nothing about TSC's internals three days ago and who was in a rush. Be warned.

I did this to overcome a maintainability issue with my code and rushed this implementation. It was also an exercise to learn more about TSC. I'm also aware that it might not be a great idea to add keywords to a language each time one gets into trouble, but if others see interest in it or you have suggestions, the branch is here https://github.com/dbarbeau/TypeScript/tree/mixes. Just don't expect this implementation to be stable/complete/anything. Actually, if it can just spark some interest/discussion on how to make mixins more useable, then I'm ok with that.

Daniel

PS: Don't get mad at me :)

PS: I'm now testing this with more "serious code", I will quickly see if it is indeed practical.

Issue 2:
As per ES6 grammar:

ExportDeclaration :
export * FromClause ;
export ExportClause FromClause ;
export ExportClause ;
export VariableStatement
export Declaration
export default HoistableDeclaration[Default]
export default [lookahead ≠ function ] AssignmentExpression[In] ;

ExportClause[NoReference] :
{ }
{ ExportsList }
{ ExportsList , }

ExportsList :
ExportSpecifier
ExportsList , ExportSpecifier

ExportSpecifier :
IdentifierName
IdentifierName as IdentifierName

FromClause :
from ModuleSpecifier

ModuleSpecifier :
StringLiteral

Meanings of export syntax that we currently do not support (doesn't list generators since we do not support them as yet)

export default function name() { }
// function name() { }
// exports.default = name;

export default function () { }
// function _temp() { }
// exports.default = _temp;

export default = expression;
// var _tmp = expression;
// exports.default = _tmp;

export { };
// Make this external module

export { } from StringLiteral;
// import __tmp = require(StringLiteral)

export { a };
//exports.a = a;

export { a } from StringLiteral;
// import __tmp = require(StringLiteral)
// exports.a = _tmp.a

export { id1 as a};
//exports.a = id1;

export { id1 as a } from StringLiteral;
// import __tmp = require(StringLiteral)
// exports.a = _tmp.id1

export * from StringLiteral
// import _tmp = require(StringLIteral)
// foreach(a in _tmp.exports)
// exports.a = _tmp.exports[a]

Few things to consider:

Resolution of export name is as follows,

if the name is directly exported clause (without referring to another module) - the resolution is returned for this name

if the name is exported using names eg. export {a} from stringLiteral - that resolution is returned

it is tried to be resolved from export entries of name (except default) from export * from StringLiteral

Should we be reporting errors for the name from export * from StringLiteral that is shadowed by the local exports/indirect named exports/existing * exports. According to ES6 it is ok, but should we still report error for shadowing for unintentional cases?

The export names are always resolved in order of local exports, indirect exports and then star exports, But typescript currently uses declaration order to determine duplicate error. Should we change this order for duplicate naming or is it ok?