-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Support TypeScript const enums #13324
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
933ba59
Compile `const enum` as normal enums
nicolo-ribaudo 9f709ff
[ts] Introduce `optimizeConstEnums` option to inline const enums
nicolo-ribaudo 2d82724
Add option to the preset
nicolo-ribaudo e37c002
Update test
nicolo-ribaudo 3301a7c
Update packages/babel-preset-typescript/test/normalize-options.spec.js
nicolo-ribaudo 2831419
Move option validation
nicolo-ribaudo File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
89 changes: 89 additions & 0 deletions
89
packages/babel-plugin-transform-typescript/src/const-enum.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import type * as t from "@babel/types"; | ||
import type { NodePath } from "@babel/traverse"; | ||
|
||
import { translateEnumValues } from "./enum"; | ||
|
||
export default function transpileConstEnum( | ||
path: NodePath<t.TSEnumDeclaration & { const: true }>, | ||
t: typeof import("@babel/types"), | ||
) { | ||
const { name } = path.node.id; | ||
|
||
const parentIsExport = path.parentPath.isExportNamedDeclaration(); | ||
let isExported = parentIsExport; | ||
if (!isExported && t.isProgram(path.parent)) { | ||
isExported = path.parent.body.some( | ||
stmt => | ||
t.isExportNamedDeclaration(stmt) && | ||
!stmt.source && | ||
stmt.specifiers.some( | ||
spec => t.isExportSpecifier(spec) && spec.local.name === name, | ||
), | ||
); | ||
} | ||
|
||
const entries = translateEnumValues(path, t); | ||
|
||
if (isExported) { | ||
const obj = t.objectExpression( | ||
entries.map(([name, value]) => | ||
t.objectProperty( | ||
t.isValidIdentifier(name) | ||
? t.identifier(name) | ||
: t.stringLiteral(name), | ||
value, | ||
), | ||
), | ||
); | ||
|
||
if (path.scope.hasOwnBinding(name)) { | ||
(parentIsExport ? path.parentPath : path).replaceWith( | ||
t.expressionStatement( | ||
t.callExpression( | ||
t.memberExpression(t.identifier("Object"), t.identifier("assign")), | ||
[path.node.id, obj], | ||
), | ||
), | ||
); | ||
} else { | ||
path.replaceWith( | ||
t.variableDeclaration("var", [t.variableDeclarator(path.node.id, obj)]), | ||
); | ||
path.scope.registerDeclaration(path); | ||
} | ||
|
||
return; | ||
} | ||
|
||
const entriesMap = new Map(entries); | ||
|
||
// TODO: After fixing https://github.com/babel/babel/pull/11065, we can | ||
// use path.scope.getBinding(name).referencePaths rather than doing | ||
// a full traversal. | ||
path.scope.path.traverse({ | ||
Scope(path) { | ||
if (path.scope.hasOwnBinding(name)) path.skip(); | ||
}, | ||
MemberExpression(path) { | ||
if (!t.isIdentifier(path.node.object, { name })) return; | ||
|
||
let key: string; | ||
if (path.node.computed) { | ||
if (t.isStringLiteral(path.node.property)) { | ||
key = path.node.property.value; | ||
} else { | ||
return; | ||
} | ||
} else if (t.isIdentifier(path.node.property)) { | ||
key = path.node.property.name; | ||
} else { | ||
return; | ||
} | ||
if (!entriesMap.has(key)) return; | ||
|
||
path.replaceWith(t.cloneNode(entriesMap.get(key))); | ||
}, | ||
}); | ||
|
||
path.remove(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1
...ages/babel-plugin-transform-typescript/test/fixtures/declarations/const-enum/options.json
This file was deleted.
Oops, something went wrong.
3 changes: 3 additions & 0 deletions
3
...babel-plugin-transform-typescript/test/fixtures/declarations/export-declare-enum/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export declare enum A {} | ||
|
||
; |
3 changes: 3 additions & 0 deletions
3
...l-plugin-transform-typescript/test/fixtures/declarations/export-declare-enum/options.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"sourceType": "module" | ||
} |
1 change: 1 addition & 0 deletions
1
...bel-plugin-transform-typescript/test/fixtures/declarations/export-declare-enum/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
; |
3 changes: 2 additions & 1 deletion
3
packages/babel-plugin-transform-typescript/test/fixtures/enum/const/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
const enum E {} | ||
// With --isolatedModules, TSC ignores the "const" modifier when compiling enums | ||
const enum E {} |
1 change: 0 additions & 1 deletion
1
packages/babel-plugin-transform-typescript/test/fixtures/enum/const/options.json
This file was deleted.
Oops, something went wrong.
4 changes: 4 additions & 0 deletions
4
packages/babel-plugin-transform-typescript/test/fixtures/enum/const/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// With --isolatedModules, TSC ignores the "const" modifier when compiling enums | ||
var E; | ||
|
||
(function (E) {})(E || (E = {})); |
11 changes: 11 additions & 0 deletions
11
...n-transform-typescript/test/fixtures/optimize-const-enums/custom-values-exported/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export const enum A { | ||
x = 3, | ||
y = "f", | ||
z = 4 << 2, | ||
w = y | ||
} | ||
|
||
A.x; | ||
A.y; | ||
A.z; | ||
A.w; |
10 changes: 10 additions & 0 deletions
10
...transform-typescript/test/fixtures/optimize-const-enums/custom-values-exported/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export var A = { | ||
x: 3, | ||
y: "f", | ||
z: 16, | ||
w: "f" | ||
}; | ||
A.x; | ||
A.y; | ||
A.z; | ||
A.w; |
11 changes: 11 additions & 0 deletions
11
...bel-plugin-transform-typescript/test/fixtures/optimize-const-enums/custom-values/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const enum A { | ||
x = 3, | ||
y = "f", | ||
z = 4 << 2, | ||
w = y | ||
} | ||
|
||
A.x; | ||
A.y; | ||
A.z; | ||
A.w; |
4 changes: 4 additions & 0 deletions
4
...l-plugin-transform-typescript/test/fixtures/optimize-const-enums/custom-values/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
3; | ||
"f"; | ||
16; | ||
"f"; |
3 changes: 3 additions & 0 deletions
3
...ges/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/declare/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
declare const enum A { x } | ||
|
||
A.x; |
1 change: 1 addition & 0 deletions
1
...s/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/declare/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0; |
3 changes: 3 additions & 0 deletions
3
...plugin-transform-typescript/test/fixtures/optimize-const-enums/export-const-enum/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const enum A { y } | ||
|
||
let x = A.y; |
4 changes: 4 additions & 0 deletions
4
...ugin-transform-typescript/test/fixtures/optimize-const-enums/export-const-enum/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export var A = { | ||
y: 0 | ||
}; | ||
let x = A.y; |
5 changes: 5 additions & 0 deletions
5
...es/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/exported/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const enum A { y } | ||
|
||
let x = A.y; | ||
|
||
export { A }; |
5 changes: 5 additions & 0 deletions
5
.../babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/exported/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
var A = { | ||
y: 0 | ||
}; | ||
let x = A.y; | ||
export { A }; |
8 changes: 8 additions & 0 deletions
8
...el-plugin-transform-typescript/test/fixtures/optimize-const-enums/local-shadowed/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
const enum A { x } | ||
|
||
{ | ||
let A = {}; | ||
A.x; | ||
} | ||
|
||
A.x; |
5 changes: 5 additions & 0 deletions
5
...-plugin-transform-typescript/test/fixtures/optimize-const-enums/local-shadowed/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
let A = {}; | ||
A.x; | ||
} | ||
0; |
8 changes: 8 additions & 0 deletions
8
packages/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/local/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
const enum A { | ||
x, y | ||
} | ||
|
||
A.x; | ||
A["y"]; | ||
A.z; | ||
A; |
4 changes: 4 additions & 0 deletions
4
...ges/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/local/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
0; | ||
1; | ||
A.z; | ||
A; |
13 changes: 13 additions & 0 deletions
13
...l-plugin-transform-typescript/test/fixtures/optimize-const-enums/merged-exported/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export const enum A { | ||
x, y | ||
} | ||
|
||
export const enum A { | ||
z | ||
} | ||
|
||
A.x; | ||
A["y"]; | ||
A.z; | ||
A.w; | ||
A; |
12 changes: 12 additions & 0 deletions
12
...plugin-transform-typescript/test/fixtures/optimize-const-enums/merged-exported/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export var A = { | ||
x: 0, | ||
y: 1 | ||
}; | ||
Object.assign(A, { | ||
z: 0 | ||
}); | ||
A.x; | ||
A["y"]; | ||
A.z; | ||
A.w; | ||
A; |
13 changes: 13 additions & 0 deletions
13
...ages/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/merged/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const enum A { | ||
x, y | ||
} | ||
|
||
const enum A { | ||
z | ||
} | ||
|
||
A.x; | ||
A["y"]; | ||
A.z; | ||
A.w; | ||
A; |
5 changes: 5 additions & 0 deletions
5
...es/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/merged/output.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
0; | ||
1; | ||
0; | ||
A.w; | ||
A; |
4 changes: 4 additions & 0 deletions
4
packages/babel-plugin-transform-typescript/test/fixtures/optimize-const-enums/options.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"plugins": [["transform-typescript", { "optimizeConstEnums": true }]], | ||
"sourceType": "module" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
packages/babel-preset-typescript/test/fixtures/opts/optimizeConstEnums/input.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const enum A { x } | ||
|
||
A.x; |
1 change: 1 addition & 0 deletions
1
packages/babel-preset-typescript/test/fixtures/opts/optimizeConstEnums/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0; |
3 changes: 3 additions & 0 deletions
3
packages/babel-preset-typescript/test/fixtures/opts/options.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"presets": [["typescript", { "optimizeConstEnums": true }]] | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we default it to
true
in next minor? I know we haveonlyRemoveTypeImports
default totrue
in Babel 8, but supporting new language features should be opt-in by default, like we did for other ES features.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we should.
In TypeScript with
--isolatedModules
, code like this works and logsx
:However, with
optimizeConstEnums
it stops working because we don't ignoreconst
anymore.For the default behavior, I'd prefer to match
--isolatedModules
as closely as possible where it's easy to do so.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, I think it should be a TS issue, they could have optimized the const enums here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript docs mentions why ambient
const enum
s (ie.declare const enum
) don't work withisolatedModules
.When
isolatedModules: false
, it seemsconst enum
anddeclare const enum
function the same.When
isolatedModules: true
, it seemsconst enum
transpiles as if it was justenum
since you get the reverse-mapped object.declare const enum
transpiles into the usual empty output, because it's expected to be inlined. However, theisolatedModules: true
will produce error:No idea why they only document
declare const enum
and notconst enum
. But I assume their reasoning of convertingconst enum
to justenum
is to have it work across modules. And I guess they treatdeclare const enum
as an error since you are explicitly saying it is ambient.Anyway, @nicolo-ribaudo. I'm not familiar with babel code, but did you make sure you also support
declare const enum
whenoptimizeConstEnums: true
? WhenisolatedModules: false
,declare const enum
seems to function the same asconst enum
, so you can just strip thedeclare
.Also, if we want to copy TypeScript functionality with
isolatedModules: true
andoptimizeConstEnums: false
, should we transpileconst enum
by treating it asenum
ie. transpile it to the reverse-mapped object instead of throwing an error?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default Babel behavior is to match
--isolatedModules
(as mentioned in our docs at the 4th caveat).Thus, this PR makes it so that by default
const enum
s are compiled to "normal" enums, which also matches the default behavior of yourbabel-plugin-const-enum
plugin. It's implemented in933ba59
(#13324).With
optimizeConstEnums: true
the plugin seems to correctly work: https://github.com/babel/babel/pull/13324/files#diff-d0d0efefe2a94935f80a8f399bbca77e2a0fbbc8e7a3ba2a1a2f07eff7bcb0de. WhenoptimizeConstEnums: false
, it produces some broken output:however, I'm not too much concerned about it because:
--isolatedMoudles
declare const enum
are not supported.