From a921f4f25fd1a0d8f2d42025fdddd252091c6336 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 22 Jun 2026 20:59:08 -0700 Subject: [PATCH 1/3] Add repro for CommonJS export destructuring emit --- ...ommonjsExportDestructuringImportedValue.js | 28 +++++++++++++++++++ ...ommonjsExportDestructuringImportedValue.ts | 13 +++++++++ 2 files changed, 41 insertions(+) create mode 100644 testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js create mode 100644 testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts diff --git a/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js b/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js new file mode 100644 index 0000000000..7fc49d8ec6 --- /dev/null +++ b/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/commonjsExportDestructuringImportedValue.ts] //// + +//// [enum.ts] +export class CodePriceType { + static A = "a"; + static B = "b"; +} + +//// [repro.ts] +import { CodePriceType } from "./enum"; +export const { A, B } = CodePriceType; + + +//// [enum.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CodePriceType = void 0; +class CodePriceType { + static A = "a"; + static B = "b"; +} +exports.CodePriceType = CodePriceType; +//// [repro.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.B = exports.A = void 0; +const enum_1 = require("./enum"); +({ A: exports.A, B: exports.B } = CodePriceType); diff --git a/testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts b/testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts new file mode 100644 index 0000000000..b834d0e17f --- /dev/null +++ b/testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts @@ -0,0 +1,13 @@ +// @target: es2022 +// @module: commonjs +// @noTypesAndSymbols: true + +// @filename: /enum.ts +export class CodePriceType { + static A = "a"; + static B = "b"; +} + +// @filename: /repro.ts +import { CodePriceType } from "./enum"; +export const { A, B } = CodePriceType; From 2b5a46150ff5336d47608fb5200d6d5ace511513 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 22 Jun 2026 21:01:19 -0700 Subject: [PATCH 2/3] Fix CommonJS export destructuring import emit --- internal/transformers/moduletransforms/commonjsmodule.go | 2 ++ .../compiler/commonjsExportDestructuringImportedValue.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/transformers/moduletransforms/commonjsmodule.go b/internal/transformers/moduletransforms/commonjsmodule.go index 0fd744bfb9..cc716a425f 100644 --- a/internal/transformers/moduletransforms/commonjsmodule.go +++ b/internal/transformers/moduletransforms/commonjsmodule.go @@ -1120,6 +1120,8 @@ func (tx *CommonJSModuleTransformer) transformInitializedVariable(node *ast.Vari // re-aliased or multi-exported names (where native destructuring cannot update all // targets) does `visitDestructuringAssignment` fall back to flattening. assignment := transformers.ConvertVariableDeclarationToAssignmentExpression(tx.EmitContext(), node) + grandparentNode := tx.pushNode(assignment) + defer tx.popNode(grandparentNode) return tx.visitDestructuringAssignment(assignment.AsBinaryExpression(), true /*valueIsDiscarded*/) } propertyAccess := tx.Factory().NewPropertyAccessExpression( diff --git a/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js b/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js index 7fc49d8ec6..9af494293c 100644 --- a/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js +++ b/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js @@ -25,4 +25,4 @@ exports.CodePriceType = CodePriceType; Object.defineProperty(exports, "__esModule", { value: true }); exports.B = exports.A = void 0; const enum_1 = require("./enum"); -({ A: exports.A, B: exports.B } = CodePriceType); +({ A: exports.A, B: exports.B } = enum_1.CodePriceType); From 2632380404f4ad88807b054702e2c9acd896ba75 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 22 Jun 2026 21:16:29 -0700 Subject: [PATCH 3/3] Add export destructuring substitution coverage --- ...ommonjsExportDestructuringImportedValue.js | 51 ++++++++++++++++++- .../namespaceExportDestructuringReferences.js | 24 +++++++++ ...ommonjsExportDestructuringImportedValue.ts | 19 +++++++ .../namespaceExportDestructuringReferences.ts | 11 ++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 testdata/baselines/reference/compiler/namespaceExportDestructuringReferences.js create mode 100644 testdata/tests/cases/compiler/namespaceExportDestructuringReferences.ts diff --git a/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js b/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js index 9af494293c..3770a97b64 100644 --- a/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js +++ b/testdata/baselines/reference/compiler/commonjsExportDestructuringImportedValue.js @@ -5,24 +5,73 @@ export class CodePriceType { static A = "a"; static B = "b"; } +export default CodePriceType; +export const pair = ["a", "b"]; +export const fallback = "fallback"; //// [repro.ts] import { CodePriceType } from "./enum"; export const { A, B } = CodePriceType; +//// [arrayPattern.ts] +import { pair } from "./enum"; +export const [ArrayA, ArrayB] = pair; + +//// [aliasedNamedObject.ts] +import { CodePriceType as PriceType } from "./enum"; +export const { A: AliasA, B: AliasB } = PriceType; + +//// [defaultObject.ts] +import CodePriceType from "./enum"; +export const { A: DefaultA, B: DefaultB } = CodePriceType; + +//// [defaultInitializer.ts] +import { CodePriceType, fallback } from "./enum"; +export const { Missing = fallback } = CodePriceType as any; + //// [enum.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.CodePriceType = void 0; +exports.fallback = exports.pair = exports.CodePriceType = void 0; class CodePriceType { static A = "a"; static B = "b"; } exports.CodePriceType = CodePriceType; +exports.default = CodePriceType; +exports.pair = ["a", "b"]; +exports.fallback = "fallback"; //// [repro.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.B = exports.A = void 0; const enum_1 = require("./enum"); ({ A: exports.A, B: exports.B } = enum_1.CodePriceType); +//// [arrayPattern.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ArrayB = exports.ArrayA = void 0; +const enum_1 = require("./enum"); +[exports.ArrayA, exports.ArrayB] = enum_1.pair; +//// [aliasedNamedObject.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AliasB = exports.AliasA = void 0; +const enum_1 = require("./enum"); +({ A: exports.AliasA, B: exports.AliasB } = enum_1.CodePriceType); +//// [defaultObject.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DefaultB = exports.DefaultA = void 0; +const enum_1 = __importDefault(require("./enum")); +({ A: exports.DefaultA, B: exports.DefaultB } = enum_1.default); +//// [defaultInitializer.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Missing = void 0; +const enum_1 = require("./enum"); +({ Missing: exports.Missing = enum_1.fallback } = enum_1.CodePriceType); diff --git a/testdata/baselines/reference/compiler/namespaceExportDestructuringReferences.js b/testdata/baselines/reference/compiler/namespaceExportDestructuringReferences.js new file mode 100644 index 0000000000..3a0f8092fa --- /dev/null +++ b/testdata/baselines/reference/compiler/namespaceExportDestructuringReferences.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/namespaceExportDestructuringReferences.ts] //// + +//// [namespaceExportDestructuringReferences.ts] +namespace N { + export const key = "a"; + export const source: any = { a: 1, b: undefined, pair: [3, 4] }; + export const fallback = 2; + + export const { [key]: computed, b = fallback } = source; + export const [x, y] = source.pair; +} + + +//// [namespaceExportDestructuringReferences.js] +"use strict"; +var N; +(function (N) { + var _a, _b, _c, _d; + N.key = "a"; + N.source = { a: 1, b: undefined, pair: [3, 4] }; + N.fallback = 2; + _a = N.source, _b = N.key, N.computed = _a[_b], _c = _a.b, N.b = _c === void 0 ? N.fallback : _c; + _d = N.source.pair, N.x = _d[0], N.y = _d[1]; +})(N || (N = {})); diff --git a/testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts b/testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts index b834d0e17f..3434be7239 100644 --- a/testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts +++ b/testdata/tests/cases/compiler/commonjsExportDestructuringImportedValue.ts @@ -7,7 +7,26 @@ export class CodePriceType { static A = "a"; static B = "b"; } +export default CodePriceType; +export const pair = ["a", "b"]; +export const fallback = "fallback"; // @filename: /repro.ts import { CodePriceType } from "./enum"; export const { A, B } = CodePriceType; + +// @filename: /arrayPattern.ts +import { pair } from "./enum"; +export const [ArrayA, ArrayB] = pair; + +// @filename: /aliasedNamedObject.ts +import { CodePriceType as PriceType } from "./enum"; +export const { A: AliasA, B: AliasB } = PriceType; + +// @filename: /defaultObject.ts +import CodePriceType from "./enum"; +export const { A: DefaultA, B: DefaultB } = CodePriceType; + +// @filename: /defaultInitializer.ts +import { CodePriceType, fallback } from "./enum"; +export const { Missing = fallback } = CodePriceType as any; diff --git a/testdata/tests/cases/compiler/namespaceExportDestructuringReferences.ts b/testdata/tests/cases/compiler/namespaceExportDestructuringReferences.ts new file mode 100644 index 0000000000..282e019520 --- /dev/null +++ b/testdata/tests/cases/compiler/namespaceExportDestructuringReferences.ts @@ -0,0 +1,11 @@ +// @target: es2022 +// @noTypesAndSymbols: true + +namespace N { + export const key = "a"; + export const source: any = { a: 1, b: undefined, pair: [3, 4] }; + export const fallback = 2; + + export const { [key]: computed, b = fallback } = source; + export const [x, y] = source.pair; +}