-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Replacing object reference before exporting causing problems #4101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
A maybe more realistic example:import {configInterface} from './config-interface';
import {defaultConfig} from './default';
import {localConfig} from './local';
import {productionConfig} from './production';
import {defaultsDeep} from 'lodash';
var config: configInterface;
if (process.env.NODE_ENV === 'production') {
config = defaultsDeep<Object, configInterface>(productionConfig, defaultConfig);
} else {
config = defaultsDeep<Object, configInterface>(localConfig, defaultConfig);
}
export {config}; If I import typescript: if (true) {
var k = {};
} else {
var k = {};
}
export {k}; compiles to: if (true) {
var k = {};
}
else {
var k = {};
} |
The current behavior is by design. we assume that the variable initialization happens at declaration site. We have talked about this before, and there is not a foolproof way of doing it. but i think a better approch is to emit the export declaration where it was in the input code relative to other statements, this way you at least have control over how it works. |
As I mentioned in the comments on #4259, emitting the export assignment at the location of the export declaration will break the following code: export { foo };
var foo = 1; Export declarations will quite often appear before the entity they're exporting. I don't know that there is a solution that doesn't have some problem, and I still think our current scheme is the best compromise. Another alternative is to put the assignment at the very end of the module, but emitting it at the place of the export declaration isn't a viable solution in my opinion. |
Just so we have all the data in one place, here are the possible solutions and their issues:
Probably the best alternative to our current scheme is to emit all the export assignments at the end of the module. But, really, we're just trading one set of issues for another. |
@ahejlsberg if we can not, or would not, emulate the ES6 semantics correctly by rewriting references, emitting the export declaration in the place it is authored is easier for users to understand. I would argue that the case reported in this issue is more common than an export declaration before the variable is assigned. also see related report in #4162. Moreover, with allowing the export declaration to be emitted at the user specified location, the user has a chance to workaround it, by moving the export declaration to the end of the file, where as the current scheme, there is no way to solve it unless you declare a new variable, and export that instead, which is not intuitive. |
Yes, emitting the export assignment at the location of the export declaration allows the user to work around the problem. But it doesn't really solve the problem. If we're going to change this, wouldn't we solve more problems by emitting the export assignments at the end of the module? Surely this would make even more real world code work correctly. I think there are far more cases of export declarations preceding the variable declaration (which would become broken) than there are cases of the module initialization code making calls to functions in other modules that access exported variables of the calling module. |
Can you rewrite all variable assignments to also assign to the export? No need for getters. The local variable and all exports are kept in sync every time the exported variable is assigned. export {foo as one, foo as two}
var foo = "hello";
foo = "world"; ...generates: var foo = exports.one = exports.two = "hello";
foo = exports.one = exports.two = "world"; Sorry to bump an old issue. |
This should be working as intended in latest. |
Hi,
If I have the following typescript code:
it compiles to:
So if I importing the object I get:
But I was expecting
7
. I.e. I was expecting the following JS code:Is this a bug or expected behavior?
I am using version
1.6.0-dev.20150731
but it has the same behavior in1.5.3
.The text was updated successfully, but these errors were encountered: