diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 8c68eafb19..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() { + 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() && 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() { + 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() && 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() && 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() { + 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)) } } diff --git a/testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.errors.txt b/testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.errors.txt new file mode 100644 index 0000000000..ba2c3dacd2 --- /dev/null +++ b/testdata/baselines/reference/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/compiler/erasableSyntaxOnlyJS.symbols b/testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.symbols new file mode 100644 index 0000000000..b6dffa7f87 --- /dev/null +++ b/testdata/baselines/reference/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/compiler/erasableSyntaxOnlyJS.types b/testdata/baselines/reference/compiler/erasableSyntaxOnlyJS.types new file mode 100644 index 0000000000..d765d1238f --- /dev/null +++ b/testdata/baselines/reference/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/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");