Preserve native destructuring for CommonJS exports to keep iterator semantics#3705
Preserve native destructuring for CommonJS exports to keep iterator semantics#3705
Conversation
Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/93212f5b-14c8-4376-8039-d01e510fd47c Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
|
This does what it says on the tin, but, I'm not sure what affect this has on @blickly Is this the change you were hoping to get? |
|
Honestly, I was expecting something more like: but this version is technically not wrong, and is definitely and improvement over the old behavior. |
|
Yeah. I think what you've suggested would be better just because it avoids the lexer problem. @copilot please try |
…ibility Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/567139d4-d663-4e26-bad2-33690c892e51 Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Reworked in 4a6c647 to emit the lexer-friendly form. For const [A, V] = foo();
exports.A = A, exports.V = V;The variable declaration is preserved as-is (so array destructuring keeps native iterator semantics), and |
With
module=commonjs, exported array destructuring was always flattened to index access, silently dropping iterator semantics:Since
downLevelIterationwas removed (and the__readhelper is not available), preserving native destructuring is the only way to keep iteration semantics for exported array patterns. Emitting the export references as separateexports.X = Xassignments (rather than e.g.[exports.A, exports.V] = foo()) keeps the output recognizable to tools likecjs-module-lexer.Changes (
internal/transformers/moduletransforms/commonjsmodule.go)visitTopLevelVariableStatement: for exported binding-pattern variable declarations, the variable declaration is now preserved as-is (so array destructuring keeps native iterator semantics) and a new helper emitsexports.X = Xfor each declared identifier.appendExportAssignmentsForBindingPattern(new): walks the binding pattern and pushes anexports.X = Xassignment for each declared identifier, recursing through nested patterns, skipping omitted elements, and handling rest and default-value elements. Comments and source-map ranges are suppressed on the synthetic export references so JSDoc on binding elements isn't duplicated on the export assignment.Side effects on existing baselines
All resulting baseline changes are improvements in the same direction: object/array patterns, defaults, and rest elements are now emitted natively, and
__restis no longer pulled in when the target supports native rest. The multi-export path (destructuringAssignmentWithExportedName) is unchanged.A new test
exportDestructuringIterator.tscovers identifiers, object patterns, defaults, and rest spread undermodule=commonjs.