TypeScript Version: nightly (2.2.0-dev.20161127)
EDIT: The issue described below is with --module commonjs, but as @aluanhaddad points out in a comment below, there are other behaviours with different module emits.
I looked for an existing issue about this but didn't find one. Apologies if this is a duplicate.
I ran into a problem with TypeScript's emit for re-exported bindings, in particular when the original exported value changes over time.
Importing a binding directly from a source module gets a 'live view' that changes when the export value changes, as it should. But importing from a re-exported binding gets a snapshot that is no longer a live view of the original export. This seems not to be spec compliant and leads to my code not working as intended.
Code
// file: a.ts
export let liveView = 'foo';
export function changeTo(val: string) { liveView = val; } // CHANGES THE EXPORT VALUE
// file: b.ts
import {liveView, changeTo} from './a'; // <===== Import directly from A
console.log(liveView); // outputs 'foo'
changeTo('bar');
console.log(liveView); // outputs 'bar' <===== GOOD: binding changed as it should
export {liveView, changeTo} from './a'; // <===== Re-export from A
// file: c.ts
import {liveView, changeTo} from './b'; // <===== Import via B's re-export
console.log(liveView); // outputs 'bar'
changeTo('baz');
console.log(liveView); // outputs 'bar' // <===== BAD: binding is not live anymore
Expected behavior
Emitted code should preserve the live binding to liveView when re-exporting from b.ts.
Last line of c.ts should output 'baz'.
Actual behavior
Emitted code exports a 'snapshot' of the liveView binding from b.ts, so that the import of liveView into c.ts is no longer a live binding.
Last line of c.ts incorrectly outputs 'bar'.
What should be the Correct Behaviour?
I found it hard to locate a clear description of correct ES6 behaviour for this situation, but from what I did find I think TypeScript's current emit is not compliant with ES6.
So for export { liveView } from 'some-module'; TypeScript emits something like:
var some_module_1 = require("some-module");
exports.liveView = some_module_1.liveView;
Whereas babel emits something like:
var _someModule = require('some-module');
Object.defineProperty(exports, 'liveView', {
enumerable: true,
get: function get() {
return _someModule.liveView;
}
});
TypeScript Version: nightly (2.2.0-dev.20161127)
EDIT: The issue described below is with
--module commonjs, but as @aluanhaddad points out in a comment below, there are other behaviours with different module emits.I looked for an existing issue about this but didn't find one. Apologies if this is a duplicate.
I ran into a problem with TypeScript's emit for re-exported bindings, in particular when the original exported value changes over time.
Importing a binding directly from a source module gets a 'live view' that changes when the export value changes, as it should. But importing from a re-exported binding gets a snapshot that is no longer a live view of the original export. This seems not to be spec compliant and leads to my code not working as intended.
Code
Expected behavior
Emitted code should preserve the live binding to
liveViewwhen re-exporting fromb.ts.Last line of
c.tsshould output'baz'.Actual behavior
Emitted code exports a 'snapshot' of the
liveViewbinding fromb.ts, so that the import ofliveViewintoc.tsis no longer a live binding.Last line of
c.tsincorrectly outputs'bar'.What should be the Correct Behaviour?
I found it hard to locate a clear description of correct ES6 behaviour for this situation, but from what I did find I think TypeScript's current emit is not compliant with ES6.
E.g. from the Exploring ES6 sections about imports as views and about re-exports
Babel emits code that preserves the 'live-ness' of re-exports
So for
export { liveView } from 'some-module';TypeScript emits something like:Whereas babel emits something like: