Skip to content

Export anonymous functions in 2 steps, declare as variable and then assign to exports. #39820

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

Merged
merged 6 commits into from
Aug 8, 2020

Conversation

josejulio
Copy link
Contributor

Fixes #39819

@typescript-bot typescript-bot added the For Milestone Bug PRs that fix a bug with a specific milestone label Jul 29, 2020
@ghost
Copy link

ghost commented Jul 29, 2020

CLA assistant check
All CLA requirements met.

@josejulio josejulio changed the title Export functions Export anonymous functions in 2 steps, declare as variable and then assign to exports. Jul 29, 2020
@josejulio
Copy link
Contributor Author

One thing that noticed, is that the comments are both set on const Var = () => and exports.Var = Var.

I found a way to remove them, but not sure if is the best.

var req;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, new Promise(function (resolve_5, reject_5) { require(['./test'], resolve_5, reject_5); })]; // FIVE
case 0: return [4 /*yield*/, import('./test')]; // FIVE
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't notice this before, but doesn't look good.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possibly missing a call to visitNode somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this with: 984e304

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but yes, a call to visitNode was missing :)

@@ -1206,7 +1207,31 @@ namespace ts {
variables = append(variables, variable);
}
else if (variable.initializer) {
expressions = append(expressions, transformInitializedVariable(variable as InitializedVariableDeclaration));
if (!isBindingPattern(variable.name) && [SyntaxKind.ArrowFunction, SyntaxKind.FunctionExpression].includes(variable.initializer.kind)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array.prototype.includes isn't guaranteed safe to use as the language service can still run in ES5 engines that don't include this method. It would be better to just use isArrowFunction(variable.initializer) || isFunctionExpression(variable.initializer) or compare the kinds directly to avoid allocating and throwing away a 2-element array object for a simple comparison.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We target ES5, but we unintentionally get ES2015+ features showing up as available due to the fact that @types/node is a devDependency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I'll update it to use isArrowFunction/isFunctionExpression.

 - Use isArrowFunction and isFunctionExpression
@@ -1206,7 +1207,31 @@ namespace ts {
variables = append(variables, variable);
}
else if (variable.initializer) {
expressions = append(expressions, transformInitializedVariable(variable as InitializedVariableDeclaration));
if (!isBindingPattern(variable.name) && (isArrowFunction(variable.initializer) || isFunctionExpression(variable.initializer))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I missed this before, but shouldn't class expressions be included in this as well? They can also be named based on the variable:

export const C = class {};

Copy link
Contributor Author

@josejulio josejulio Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, I forgot about them.
I'll update to consider them too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

- Consider ClassExpresion, they can also be named based on the
  variable.
@rbuckton
Copy link
Member

Since the issue for this is marked for 4.1, I have to wait to merge this until tomorrow at the earliest.

@josejulio
Copy link
Contributor Author

@rbuckton wonder if this can be merged already now that there is a release-4.0 branch.

Thanks!

@rbuckton rbuckton merged commit 668bbc6 into microsoft:master Aug 8, 2020
@rbuckton
Copy link
Member

rbuckton commented Aug 8, 2020

Thanks for the reminder, this has been merged :)

@josejulio josejulio deleted the export-functions branch August 8, 2020 01:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Milestone Bug PRs that fix a bug with a specific milestone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Directly exporting an (arrow) function prevents it from being named
3 participants