From de0d81271f12b8decbc73033c42a7ea03147b6b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 25 Oct 2025 19:07:09 +0000 Subject: [PATCH 1/6] Initial plan From a53300abb9f61cda8a5af9276fafd1e667ad2f42 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 25 Oct 2025 19:25:29 +0000 Subject: [PATCH 2/6] Skip erasableSyntaxOnly checks for JavaScript files 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 <5341706+jakebailey@users.noreply.github.com> --- internal/checker/checker.go | 12 +++--- .../compiler/erasableSyntaxOnlyJS.errors.txt | 23 +++++++++++ .../compiler/erasableSyntaxOnlyJS.symbols | 30 ++++++++++++++ .../erasableSyntaxOnlyJS.symbols.diff | 34 ++++++++++++++++ .../compiler/erasableSyntaxOnlyJS.types | 36 +++++++++++++++++ .../erasableSyntaxOnlyJS.errors.txt.diff | 27 +++++++++++++ .../compiler/erasableSyntaxOnlyJS.types.diff | 40 +++++++++++++++++++ 7 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.errors.txt create mode 100644 testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols create mode 100644 testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff create mode 100644 testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.types create mode 100644 testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff create mode 100644 testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 8c68eafb19..3e817873f6 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -2488,7 +2488,7 @@ func (c *Checker) checkParameter(node *ast.Node) { paramName = node.Name().Text() } if ast.HasSyntacticModifier(node, ast.ModifierFlagsParameterPropertyModifier) { - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() { + if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } if !(ast.IsConstructorDeclaration(fn) && ast.NodeIsPresent(fn.Body())) { @@ -4843,7 +4843,7 @@ func (c *Checker) checkEnumDeclaration(node *ast.Node) { c.checkExportsOnMergedDeclarations(node) c.checkSourceElements(node.Members()) - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && node.Flags&ast.NodeFlagsAmbient == 0 { + if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) && node.Flags&ast.NodeFlagsAmbient == 0 { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } @@ -4933,7 +4933,7 @@ func (c *Checker) checkModuleDeclaration(node *ast.Node) { symbol := c.getSymbolOfDeclaration(node) // The following checks only apply on a non-ambient instantiated module declaration. if symbol.Flags&ast.SymbolFlagsValueModule != 0 && !inAmbientContext && isInstantiatedModule(node, c.compilerOptions.ShouldPreserveConstEnums()) { - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() { + if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } if c.compilerOptions.GetIsolatedModules() && ast.GetSourceFileOfNode(node).ExternalModuleIndicator == nil { @@ -5232,7 +5232,7 @@ func (c *Checker) checkImportEqualsDeclaration(node *ast.Node) { return // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. } c.checkGrammarModifiers(node) - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && node.Flags&ast.NodeFlagsAmbient == 0 { + if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) && node.Flags&ast.NodeFlagsAmbient == 0 { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } if ast.IsInternalModuleImportEqualsDeclaration(node) || c.checkExternalImportOrExportDeclaration(node) { @@ -5334,7 +5334,7 @@ func (c *Checker) checkExportAssignment(node *ast.Node) { if c.checkGrammarModuleElementContext(node, illegalContextMessage) { return // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors. } - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && node.AsExportAssignment().IsExportEquals && node.Flags&ast.NodeFlagsAmbient == 0 { + if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) && node.AsExportAssignment().IsExportEquals && node.Flags&ast.NodeFlagsAmbient == 0 { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } container := node.Parent @@ -11832,7 +11832,7 @@ func (c *Checker) classDeclarationExtendsNull(classDecl *ast.Node) bool { func (c *Checker) checkAssertion(node *ast.Node, checkMode CheckMode) *Type { if node.Kind == ast.KindTypeAssertionExpression { - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() { + if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) { c.diagnostics.Add(ast.NewDiagnostic(ast.GetSourceFileOfNode(node), core.NewTextRange(scanner.SkipTrivia(ast.GetSourceFileOfNode(node).Text(), node.Pos()), node.Expression().Pos()), diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled)) } } diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.errors.txt b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.errors.txt new file mode 100644 index 0000000000..ba2c3dacd2 --- /dev/null +++ b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.errors.txt @@ -0,0 +1,23 @@ +index.ts(2,1): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. +index.ts(3,1): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. + + +==== index.ts (2 errors) ==== + // These should still error because they are in a TypeScript file + import bar = require("./bar.cjs"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. + import foo = require("./foo.js"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. + +==== bar.cjs (0 errors) ==== + module.exports = { + a: 1, + } + +==== foo.js (0 errors) ==== + module.exports = { + b: 2, + } + \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols new file mode 100644 index 0000000000..b6dffa7f87 --- /dev/null +++ b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/erasableSyntaxOnlyJS.ts] //// + +=== index.ts === +// These should still error because they are in a TypeScript file +import bar = require("./bar.cjs"); +>bar : Symbol(bar, Decl(index.ts, 0, 0)) + +import foo = require("./foo.js"); +>foo : Symbol(foo, Decl(index.ts, 1, 34)) + +=== bar.cjs === +module.exports = { +>module.exports : Symbol(export=, Decl(bar.cjs, 0, 0)) +>module : Symbol(module.exports) +>exports : Symbol(export=, Decl(bar.cjs, 0, 0)) + + a: 1, +>a : Symbol(a, Decl(bar.cjs, 0, 18)) +} + +=== foo.js === +module.exports = { +>module.exports : Symbol(export=, Decl(foo.js, 0, 0)) +>module : Symbol(module.exports) +>exports : Symbol(export=, Decl(foo.js, 0, 0)) + + b: 2, +>b : Symbol(b, Decl(foo.js, 0, 18)) +} + diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff new file mode 100644 index 0000000000..b35de662a5 --- /dev/null +++ b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff @@ -0,0 +1,34 @@ +--- old.erasableSyntaxOnlyJS.symbols ++++ new.erasableSyntaxOnlyJS.symbols +@@= skipped -0, +0 lines =@@ +- ++//// [tests/cases/compiler/erasableSyntaxOnlyJS.ts] //// ++ ++=== index.ts === ++// These should still error because they are in a TypeScript file ++import bar = require("./bar.cjs"); ++>bar : Symbol(bar, Decl(index.ts, 0, 0)) ++ ++import foo = require("./foo.js"); ++>foo : Symbol(foo, Decl(index.ts, 1, 34)) ++ ++=== bar.cjs === ++module.exports = { ++>module.exports : Symbol(export=, Decl(bar.cjs, 0, 0)) ++>module : Symbol(module.exports) ++>exports : Symbol(export=, Decl(bar.cjs, 0, 0)) ++ ++ a: 1, ++>a : Symbol(a, Decl(bar.cjs, 0, 18)) ++} ++ ++=== foo.js === ++module.exports = { ++>module.exports : Symbol(export=, Decl(foo.js, 0, 0)) ++>module : Symbol(module.exports) ++>exports : Symbol(export=, Decl(foo.js, 0, 0)) ++ ++ b: 2, ++>b : Symbol(b, Decl(foo.js, 0, 18)) ++} ++ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.types b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.types new file mode 100644 index 0000000000..d765d1238f --- /dev/null +++ b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.types @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/erasableSyntaxOnlyJS.ts] //// + +=== index.ts === +// These should still error because they are in a TypeScript file +import bar = require("./bar.cjs"); +>bar : { a: number; } + +import foo = require("./foo.js"); +>foo : { b: number; } + +=== bar.cjs === +module.exports = { +>module.exports = { a: 1,} : { a: number; } +>module.exports : { a: number; } +>module : { "export=": { a: number; }; } +>exports : { a: number; } +>{ a: 1,} : { a: number; } + + a: 1, +>a : number +>1 : 1 +} + +=== foo.js === +module.exports = { +>module.exports = { b: 2,} : { b: number; } +>module.exports : { b: number; } +>module : { "export=": { b: number; }; } +>exports : { b: number; } +>{ b: 2,} : { b: number; } + + b: 2, +>b : number +>2 : 2 +} + diff --git a/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff new file mode 100644 index 0000000000..89e4c68be7 --- /dev/null +++ b/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff @@ -0,0 +1,27 @@ +--- old.erasableSyntaxOnlyJS.errors.txt ++++ new.erasableSyntaxOnlyJS.errors.txt +@@= skipped -0, +0 lines =@@ +- ++index.ts(2,1): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. ++index.ts(3,1): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. ++ ++ ++==== index.ts (2 errors) ==== ++ // These should still error because they are in a TypeScript file ++ import bar = require("./bar.cjs"); ++ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++!!! error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. ++ import foo = require("./foo.js"); ++ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++!!! error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. ++ ++==== bar.cjs (0 errors) ==== ++ module.exports = { ++ a: 1, ++ } ++ ++==== foo.js (0 errors) ==== ++ module.exports = { ++ b: 2, ++ } ++ \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff b/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff new file mode 100644 index 0000000000..78f6b5ce18 --- /dev/null +++ b/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff @@ -0,0 +1,40 @@ +--- old.erasableSyntaxOnlyJS.types ++++ new.erasableSyntaxOnlyJS.types +@@= skipped -0, +0 lines =@@ +- ++//// [tests/cases/compiler/erasableSyntaxOnlyJS.ts] //// ++ ++=== index.ts === ++// These should still error because they are in a TypeScript file ++import bar = require("./bar.cjs"); ++>bar : { a: number; } ++ ++import foo = require("./foo.js"); ++>foo : { b: number; } ++ ++=== bar.cjs === ++module.exports = { ++>module.exports = { a: 1,} : { a: number; } ++>module.exports : { a: number; } ++>module : { "export=": { a: number; }; } ++>exports : { a: number; } ++>{ a: 1,} : { a: number; } ++ ++ a: 1, ++>a : number ++>1 : 1 ++} ++ ++=== foo.js === ++module.exports = { ++>module.exports = { b: 2,} : { b: number; } ++>module.exports : { b: number; } ++>module : { "export=": { b: number; }; } ++>exports : { b: number; } ++>{ b: 2,} : { b: number; } ++ ++ b: 2, ++>b : number ++>2 : 2 ++} ++ \ No newline at end of file From 838114c77e011b02f7c70733ec5d415b7ab888bd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 25 Oct 2025 19:28:30 +0000 Subject: [PATCH 3/6] Update TypeScript submodule with new test --- _submodules/TypeScript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_submodules/TypeScript b/_submodules/TypeScript index 050a6f8127..871d25cd64 160000 --- a/_submodules/TypeScript +++ b/_submodules/TypeScript @@ -1 +1 @@ -Subproject commit 050a6f8127f54ce64c79ee992b9f0e27d0d712a2 +Subproject commit 871d25cd64d7a0e169b831c3a01d16a1cfb3ba2d From f697c9060cf9bf877a673b14746e687e93693289 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 25 Oct 2025 20:39:11 +0000 Subject: [PATCH 4/6] Restore TypeScript submodule to correct commit 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 <5341706+jakebailey@users.noreply.github.com> --- _submodules/TypeScript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_submodules/TypeScript b/_submodules/TypeScript index 871d25cd64..050a6f8127 160000 --- a/_submodules/TypeScript +++ b/_submodules/TypeScript @@ -1 +1 @@ -Subproject commit 871d25cd64d7a0e169b831c3a01d16a1cfb3ba2d +Subproject commit 050a6f8127f54ce64c79ee992b9f0e27d0d712a2 From 8873bcbfd083a3803d1625b53dcecf91172645e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 25 Oct 2025 21:30:29 +0000 Subject: [PATCH 5/6] Move test to local compiler test directory 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 <5341706+jakebailey@users.noreply.github.com> --- .../compiler/erasableSyntaxOnlyJS.errors.txt | 0 .../compiler/erasableSyntaxOnlyJS.symbols | 0 .../compiler/erasableSyntaxOnlyJS.types | 0 .../erasableSyntaxOnlyJS.symbols.diff | 34 ---------------- .../erasableSyntaxOnlyJS.errors.txt.diff | 27 ------------- .../compiler/erasableSyntaxOnlyJS.types.diff | 40 ------------------- .../cases/compiler/erasableSyntaxOnlyJS.ts | 22 ++++++++++ 7 files changed, 22 insertions(+), 101 deletions(-) rename testdata/baselines/reference/{submodule => }/compiler/erasableSyntaxOnlyJS.errors.txt (100%) rename testdata/baselines/reference/{submodule => }/compiler/erasableSyntaxOnlyJS.symbols (100%) rename testdata/baselines/reference/{submodule => }/compiler/erasableSyntaxOnlyJS.types (100%) delete mode 100644 testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff delete mode 100644 testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff delete mode 100644 testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff create mode 100644 testdata/tests/cases/compiler/erasableSyntaxOnlyJS.ts diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.errors.txt b/testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.errors.txt similarity index 100% rename from testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.errors.txt rename to testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.errors.txt diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols b/testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.symbols similarity index 100% rename from testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols rename to testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.symbols diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.types b/testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.types similarity index 100% rename from testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.types rename to testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.types diff --git a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff b/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff deleted file mode 100644 index b35de662a5..0000000000 --- a/testdata/baselines/reference/submodule/compiler/erasableSyntaxOnlyJS.symbols.diff +++ /dev/null @@ -1,34 +0,0 @@ ---- old.erasableSyntaxOnlyJS.symbols -+++ new.erasableSyntaxOnlyJS.symbols -@@= skipped -0, +0 lines =@@ -- -+//// [tests/cases/compiler/erasableSyntaxOnlyJS.ts] //// -+ -+=== index.ts === -+// These should still error because they are in a TypeScript file -+import bar = require("./bar.cjs"); -+>bar : Symbol(bar, Decl(index.ts, 0, 0)) -+ -+import foo = require("./foo.js"); -+>foo : Symbol(foo, Decl(index.ts, 1, 34)) -+ -+=== bar.cjs === -+module.exports = { -+>module.exports : Symbol(export=, Decl(bar.cjs, 0, 0)) -+>module : Symbol(module.exports) -+>exports : Symbol(export=, Decl(bar.cjs, 0, 0)) -+ -+ a: 1, -+>a : Symbol(a, Decl(bar.cjs, 0, 18)) -+} -+ -+=== foo.js === -+module.exports = { -+>module.exports : Symbol(export=, Decl(foo.js, 0, 0)) -+>module : Symbol(module.exports) -+>exports : Symbol(export=, Decl(foo.js, 0, 0)) -+ -+ b: 2, -+>b : Symbol(b, Decl(foo.js, 0, 18)) -+} -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff b/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff deleted file mode 100644 index 89e4c68be7..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.errors.txt.diff +++ /dev/null @@ -1,27 +0,0 @@ ---- old.erasableSyntaxOnlyJS.errors.txt -+++ new.erasableSyntaxOnlyJS.errors.txt -@@= skipped -0, +0 lines =@@ -- -+index.ts(2,1): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. -+index.ts(3,1): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. -+ -+ -+==== index.ts (2 errors) ==== -+ // These should still error because they are in a TypeScript file -+ import bar = require("./bar.cjs"); -+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+!!! error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. -+ import foo = require("./foo.js"); -+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+!!! error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. -+ -+==== bar.cjs (0 errors) ==== -+ module.exports = { -+ a: 1, -+ } -+ -+==== foo.js (0 errors) ==== -+ module.exports = { -+ b: 2, -+ } -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff b/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff deleted file mode 100644 index 78f6b5ce18..0000000000 --- a/testdata/baselines/reference/submoduleAccepted/compiler/erasableSyntaxOnlyJS.types.diff +++ /dev/null @@ -1,40 +0,0 @@ ---- old.erasableSyntaxOnlyJS.types -+++ new.erasableSyntaxOnlyJS.types -@@= skipped -0, +0 lines =@@ -- -+//// [tests/cases/compiler/erasableSyntaxOnlyJS.ts] //// -+ -+=== index.ts === -+// These should still error because they are in a TypeScript file -+import bar = require("./bar.cjs"); -+>bar : { a: number; } -+ -+import foo = require("./foo.js"); -+>foo : { b: number; } -+ -+=== bar.cjs === -+module.exports = { -+>module.exports = { a: 1,} : { a: number; } -+>module.exports : { a: number; } -+>module : { "export=": { a: number; }; } -+>exports : { a: number; } -+>{ a: 1,} : { a: number; } -+ -+ a: 1, -+>a : number -+>1 : 1 -+} -+ -+=== foo.js === -+module.exports = { -+>module.exports = { b: 2,} : { b: number; } -+>module.exports : { b: number; } -+>module : { "export=": { b: number; }; } -+>exports : { b: number; } -+>{ b: 2,} : { b: number; } -+ -+ b: 2, -+>b : number -+>2 : 2 -+} -+ \ No newline at end of file diff --git a/testdata/tests/cases/compiler/erasableSyntaxOnlyJS.ts b/testdata/tests/cases/compiler/erasableSyntaxOnlyJS.ts new file mode 100644 index 0000000000..8a134f70eb --- /dev/null +++ b/testdata/tests/cases/compiler/erasableSyntaxOnlyJS.ts @@ -0,0 +1,22 @@ +// @erasableSyntaxOnly: true +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// JavaScript files should not have erasableSyntaxOnly checks +// because they are already "erased" by definition. + +// @Filename: bar.cjs +module.exports = { + a: 1, +} + +// @Filename: foo.js +module.exports = { + b: 2, +} + +// @Filename: index.ts +// These should still error because they are in a TypeScript file +import bar = require("./bar.cjs"); +import foo = require("./foo.js"); From 34d6b826801650e8d3312e328fc236519fd16f71 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Oct 2025 17:58:07 +0000 Subject: [PATCH 6/6] Extract erasableSyntaxOnly check into helper method 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 <5341706+jakebailey@users.noreply.github.com> --- internal/checker/checker.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 3e817873f6..480fef695c 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -2475,6 +2475,10 @@ func (c *Checker) checkTypeParameterDeferred(node *ast.Node) { } } +func (c *Checker) shouldCheckErasableSyntax(node *ast.Node) bool { + return c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) +} + func (c *Checker) checkParameter(node *ast.Node) { // Grammar checking // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the @@ -2488,7 +2492,7 @@ func (c *Checker) checkParameter(node *ast.Node) { paramName = node.Name().Text() } if ast.HasSyntacticModifier(node, ast.ModifierFlagsParameterPropertyModifier) { - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) { + if c.shouldCheckErasableSyntax(node) { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } if !(ast.IsConstructorDeclaration(fn) && ast.NodeIsPresent(fn.Body())) { @@ -4843,7 +4847,7 @@ func (c *Checker) checkEnumDeclaration(node *ast.Node) { c.checkExportsOnMergedDeclarations(node) c.checkSourceElements(node.Members()) - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) && node.Flags&ast.NodeFlagsAmbient == 0 { + if c.shouldCheckErasableSyntax(node) && node.Flags&ast.NodeFlagsAmbient == 0 { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } @@ -4933,7 +4937,7 @@ func (c *Checker) checkModuleDeclaration(node *ast.Node) { symbol := c.getSymbolOfDeclaration(node) // The following checks only apply on a non-ambient instantiated module declaration. if symbol.Flags&ast.SymbolFlagsValueModule != 0 && !inAmbientContext && isInstantiatedModule(node, c.compilerOptions.ShouldPreserveConstEnums()) { - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) { + if c.shouldCheckErasableSyntax(node) { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } if c.compilerOptions.GetIsolatedModules() && ast.GetSourceFileOfNode(node).ExternalModuleIndicator == nil { @@ -5232,7 +5236,7 @@ func (c *Checker) checkImportEqualsDeclaration(node *ast.Node) { return // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. } c.checkGrammarModifiers(node) - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) && node.Flags&ast.NodeFlagsAmbient == 0 { + if c.shouldCheckErasableSyntax(node) && node.Flags&ast.NodeFlagsAmbient == 0 { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } if ast.IsInternalModuleImportEqualsDeclaration(node) || c.checkExternalImportOrExportDeclaration(node) { @@ -5334,7 +5338,7 @@ func (c *Checker) checkExportAssignment(node *ast.Node) { if c.checkGrammarModuleElementContext(node, illegalContextMessage) { return // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors. } - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) && node.AsExportAssignment().IsExportEquals && node.Flags&ast.NodeFlagsAmbient == 0 { + if c.shouldCheckErasableSyntax(node) && node.AsExportAssignment().IsExportEquals && node.Flags&ast.NodeFlagsAmbient == 0 { c.error(node, diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled) } container := node.Parent @@ -11832,7 +11836,7 @@ func (c *Checker) classDeclarationExtendsNull(classDecl *ast.Node) bool { func (c *Checker) checkAssertion(node *ast.Node, checkMode CheckMode) *Type { if node.Kind == ast.KindTypeAssertionExpression { - if c.compilerOptions.ErasableSyntaxOnly.IsTrue() && !ast.IsInJSFile(node) { + if c.shouldCheckErasableSyntax(node) { c.diagnostics.Add(ast.NewDiagnostic(ast.GetSourceFileOfNode(node), core.NewTextRange(scanner.SkipTrivia(ast.GetSourceFileOfNode(node).Text(), node.Pos()), node.Expression().Pos()), diagnostics.This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled)) } }