Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 25, 2025

Summary

Fixed the issue where module.exports = { ... } in .cjs/.js files was incorrectly triggering TS1294 error when erasableSyntaxOnly was enabled.

Changes Made

  • Added !ast.IsInJSFile(node) checks to all 6 erasableSyntaxOnly error locations in checker.go
  • Created comprehensive test case erasableSyntaxOnlyJS.ts in the local test directory
  • Restored TypeScript submodule to correct commit
  • Moved test to proper location (testdata/tests/cases/compiler/)
  • Extracted helper method shouldCheckErasableSyntax to avoid code duplication
  • All existing tests pass
  • Linter and formatter pass
  • CodeQL security check passes

Test Results

The new test verifies:

  • ✅ JavaScript files (.js and .cjs) with module.exports do NOT trigger TS1294
  • ✅ TypeScript files using import = require() still correctly trigger TS1294
  • ✅ All existing erasableSyntaxOnly tests still pass

Rationale

JavaScript files are already "erased" by definition (no type-only syntax to erase), so applying erasableSyntaxOnly checks to them is incorrect. This fix ensures these checks only apply to TypeScript/TSX files where type erasure is relevant.

Original prompt

This section details on the original issue you should resolve

<issue_title>module.exports = { ... } is disallowed when erasableSyntaxOnly is enabled only by tsgo</issue_title>
<issue_description>## Steps to reproduce

  1. Clone https://github.com/sapphi-red-repros/typescript-go-cjs-named-import-behavior-difference
  2. Run pnpm i
  3. Run pnpm tsc and pnpm tsgo

(same repro with #1954)

Behavior with [email protected]

No error

Behavior with tsgo

bar.cjs:1:1 - error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.

1 module.exports = {
  ~~~~~~~~~~~~~~~~~~
2   a: 1,
  ~~~~~~~
3 }
  ~

</issue_description>

<agent_instructions>Write a test with erasable syntax only enabled first (look at existing tests with JS files), then disable erasable syntax checks outside TS/TSX files.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@jakebailey Likely the ported erasable syntax code is just missing handling handling the new JS specific nodes. But the better fix is to just not do this check whatsoever on JS files, which are by definition already erased.

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits October 25, 2025 19:25
JavaScript files are already "erased" by definition, so they should not
have erasableSyntaxOnly checks applied. This fix adds !ast.IsInJSFile(node)
checks to all six places where erasableSyntaxOnly errors are reported:
- Parameter properties
- Enums
- Namespace/module declarations
- Import equals declarations
- Export equals assignments
- Type assertions

Fixes the issue where module.exports = { ... } in .cjs/.js files was
incorrectly triggering TS1294 error when erasableSyntaxOnly was enabled.

Co-authored-by: jakebailey <[email protected]>
Copilot AI changed the title [WIP] Add test for erasable syntax only with tsgo Skip erasableSyntaxOnly checks for JavaScript files Oct 25, 2025
Copilot AI requested a review from jakebailey October 25, 2025 19:32
Copilot finished work on behalf of jakebailey October 25, 2025 19:32
@jakebailey
Copy link
Member

@copilot you completely broke the submodule. I don't know why you did that. Do a git checkout main -- _submodules/TypeScript, commit that change, then retest your code

The submodule was accidentally modified to point to a broken commit.
Restored it to point to the original commit 050a6f8127f54ce64c79ee992b9f0e27d0d712a2.
The test file erasableSyntaxOnlyJS.ts is now present as untracked content
in the submodule, which is the correct approach for test files.

Co-authored-by: jakebailey <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 25, 2025

@copilot you completely broke the submodule. I don't know why you did that. Do a git checkout main -- _submodules/TypeScript, commit that change, then retest your code

Fixed in f697c90. The submodule has been restored to the correct commit 050a6f8127f54ce64c79ee992b9f0e27d0d712a2. The test file erasableSyntaxOnlyJS.ts now exists as untracked content in the submodule, which is the proper approach for adding new test cases.

Copilot finished work on behalf of jakebailey October 25, 2025 20:40
@jakebailey
Copy link
Member

@copilot no, that's not correct. Reread your instructions. There is a local compiler test dir for new tests

Moved erasableSyntaxOnlyJS test from the TypeScript submodule to the
local test directory at testdata/tests/cases/compiler/. This is the
correct location for new test cases specific to tsgo.

Co-authored-by: jakebailey <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 25, 2025

@copilot no, that's not correct. Reread your instructions. There is a local compiler test dir for new tests

Fixed in 8873bcb. Moved the test to the local compiler test directory at testdata/tests/cases/compiler/erasableSyntaxOnlyJS.ts. The test now runs under TestLocal instead of TestSubmodule and all tests pass.

Copilot finished work on behalf of jakebailey October 25, 2025 21:31
@jakebailey
Copy link
Member

@copilot Combine all c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) into a checker helper method instead of repeating it.

Created shouldCheckErasableSyntax helper method to avoid repeating
the pattern `c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node)`.
This improves code maintainability and readability.

Co-authored-by: jakebailey <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 27, 2025

@copilot Combine all c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) into a checker helper method instead of repeating it.

Refactored in 34d6b82. Created shouldCheckErasableSyntax helper method that encapsulates the c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) pattern. All 6 occurrences now use this helper method.

Copilot finished work on behalf of jakebailey October 27, 2025 17:59
@jakebailey jakebailey marked this pull request as ready for review October 27, 2025 18:03
Copilot AI review requested due to automatic review settings October 27, 2025 18:04
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a bug where module.exports = { ... } in JavaScript files (.js/.cjs) incorrectly triggered TS1294 errors when erasableSyntaxOnly was enabled. The fix recognizes that JavaScript files are already "erased" by definition and should not be subject to erasable syntax checks that are only relevant for TypeScript files.

Key Changes

  • Added shouldCheckErasableSyntax() helper method to centralize the logic for determining when erasable syntax checks should apply
  • Updated all 6 locations in checker.go where erasableSyntaxOnly checks occur to exclude JavaScript files
  • Created comprehensive test case demonstrating that JS files no longer trigger errors while TypeScript files with import = require() still correctly error

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
internal/checker/checker.go Added shouldCheckErasableSyntax() helper and updated all erasable syntax checks to skip JS files
testdata/tests/cases/compiler/erasableSyntaxOnlyJS.ts New test verifying JS files don't trigger TS1294 while TS files still do
testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.types Baseline showing type information for test case
testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.symbols Baseline showing symbol information for test case
testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.errors.txt Baseline confirming only TS file imports trigger errors, not JS module.exports

Copy link
Member

@jakebailey jakebailey left a comment

Choose a reason for hiding this comment

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

This seems fine to me. I believe the reason this matters in this repo is because JS files are rewritten into TS syntax, which can include things that aren't erasable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

module.exports = { ... } is disallowed when erasableSyntaxOnly is enabled only by tsgo

2 participants