Implement TypeScript 6.0 deprecation of module keyword for namespaces

Co-authored-by: DanielRosenwasser <972891+DanielRosenwasser@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-09-03 23:33:52 +00:00
parent 88b137f319
commit 7cbbb7e307
5 changed files with 145 additions and 49 deletions

View File

@ -1132,13 +1132,15 @@ import {
walkUpBindingElementsAndPatterns,
walkUpOuterExpressions,
walkUpParenthesizedExpressions,
walkUpParenthesizedTypes,
walkUpParenthesizedTypesAndGetParentAndChild,
WhileStatement,
WideningContext,
WithStatement,
WriterContextOut,
YieldExpression,
walkUpParenthesizedTypes,
walkUpParenthesizedTypesAndGetParentAndChild,
Version,
versionMajorMinor,
WhileStatement,
WideningContext,
WithStatement,
WriterContextOut,
YieldExpression,
} from "./_namespaces/ts.js";
import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers.js";
import * as performance from "./_namespaces/ts.performance.js";
@ -47992,16 +47994,47 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
if (isIdentifier(node.name)) {
checkCollisionsForDeclarationName(node, node.name);
if (!(node.flags & (NodeFlags.Namespace | NodeFlags.GlobalAugmentation))) {
const sourceFile = getSourceFileOfNode(node);
const pos = getNonModifierTokenPosOfNode(node);
const span = getSpanOfTokenAtPosition(sourceFile, pos);
suggestionDiagnostics.add(
createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.A_namespace_declaration_should_not_be_declared_using_the_module_keyword_Please_use_the_namespace_keyword_instead),
);
}
if (isIdentifier(node.name)) {
checkCollisionsForDeclarationName(node, node.name);
if (!(node.flags & (NodeFlags.Namespace | NodeFlags.GlobalAugmentation))) {
const sourceFile = getSourceFileOfNode(node);
const pos = getNonModifierTokenPosOfNode(node);
const span = getSpanOfTokenAtPosition(sourceFile, pos);
// Check if we should generate an error (TS 6.0+) or suggestion (older versions)
const currentVersion = new Version(versionMajorMinor);
const errorVersion = new Version("6.0");
const shouldError = currentVersion.compareTo(errorVersion) >= Comparison.EqualTo;
// Check if ignoreDeprecations should suppress this error
let shouldSuppress = false;
if (shouldError && compilerOptions.ignoreDeprecations) {
// Only valid ignoreDeprecations values: "5.0" and "6.0"
if (compilerOptions.ignoreDeprecations === "6.0") {
shouldSuppress = true;
}
}
if (shouldError && !shouldSuppress) {
// In TypeScript 6.0+, this is an error unless suppressed by ignoreDeprecations
const errorDiagnostic = createFileDiagnostic(
sourceFile,
span.start,
span.length,
Diagnostics.The_module_keyword_is_not_allowed_for_namespace_declarations_Use_the_namespace_keyword_instead
);
diagnostics.add(errorDiagnostic);
} else {
// In older versions or when suppressed, keep as suggestion
const suggestionDiagnostic = createFileDiagnostic(
sourceFile,
span.start,
span.length,
Diagnostics.A_namespace_declaration_should_not_be_declared_using_the_module_keyword_Please_use_the_namespace_keyword_instead
);
suggestionDiagnostics.add(suggestionDiagnostic);
}
}
}
checkExportsOnMergedDeclarations(node);

View File

@ -1820,10 +1820,14 @@
"category": "Error",
"code": 1539
},
"A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.": {
"category": "Suggestion",
"code": 1540,
"reportsDeprecated": true
"A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.": {
"category": "Suggestion",
"code": 1540,
"reportsDeprecated": true
},
"The 'module' keyword is not allowed for namespace declarations. Use the 'namespace' keyword instead.": {
"category": "Error",
"code": 1547
},
"Type-only import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.": {
"category": "Error",

View File

@ -0,0 +1,27 @@
///<reference path="fourslash.ts" />
// @Filename: a.ts
////[|module|] mod1 { export let x: number }
////declare [|module|] mod2 { export let x: number }
////export [|module|] mod3 { export let x: number }
////export declare [|module|] mod4 { export let x: number }
////namespace mod5 { export let x: number }
////declare namespace mod6 { export let x: number }
////mod1.x = 1;
////mod2.x = 1;
////mod5.x = 1;
////mod6.x = 1;
// @Filename: b.ts
////declare module "global-ambient-module" {}
goTo.file("a.ts")
const errorDiagnostics = test.ranges().map(range => ({
code: 1547,
message: "The 'module' keyword is not allowed for namespace declarations. Use the 'namespace' keyword instead.",
range,
}));
verify.getSemanticDiagnostics(errorDiagnostics)
goTo.file("b.ts")
verify.getSemanticDiagnostics([])

View File

@ -0,0 +1,31 @@
///<reference path="fourslash.ts" />
// @ignoreDeprecations: 6.0
// @Filename: a.ts
////[|module|] mod1 { export let x: number }
////declare [|module|] mod2 { export let x: number }
////export [|module|] mod3 { export let x: number }
////export declare [|module|] mod4 { export let x: number }
////namespace mod5 { export let x: number }
////declare namespace mod6 { export let x: number }
////declare module "module-augmentation" {}
////declare global {}
////mod1.x = 1;
////mod2.x = 1;
////mod5.x = 1;
////mod6.x = 1;
// @Filename: b.ts
////module "global-ambient-module" {}
goTo.file("a.ts")
const diagnostics = test.ranges().map(range => ({
code: 1540,
message: "A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.",
reportsDeprecated: true as true,
range,
}));
verify.getSuggestionDiagnostics(diagnostics)
goTo.file("b.ts")
verify.getSuggestionDiagnostics([])

View File

@ -1,30 +1,31 @@
///<reference path="fourslash.ts" />
// @Filename: a.ts
////[|module|] mod1 { export let x: number }
////declare [|module|] mod2 { export let x: number }
////export [|module|] mod3 { export let x: number }
////export declare [|module|] mod4 { export let x: number }
////namespace mod5 { export let x: number }
////declare namespace mod6 { export let x: number }
////declare module "module-augmentation" {}
////declare global {}
////mod1.x = 1;
////mod2.x = 1;
////mod5.x = 1;
////mod6.x = 1;
// @Filename: b.ts
////module "global-ambient-module" {}
goTo.file("a.ts")
const diagnostics = test.ranges().map(range => ({
code: 1540,
message: "A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.",
reportsDeprecated: true,
range,
}));
verify.getSuggestionDiagnostics(diagnostics)
goTo.file("b.ts")
///<reference path="fourslash.ts" />
// @ignoreDeprecations: 6.0
// @Filename: a.ts
////[|module|] mod1 { export let x: number }
////declare [|module|] mod2 { export let x: number }
////export [|module|] mod3 { export let x: number }
////export declare [|module|] mod4 { export let x: number }
////namespace mod5 { export let x: number }
////declare namespace mod6 { export let x: number }
////declare module "module-augmentation" {}
////declare global {}
////mod1.x = 1;
////mod2.x = 1;
////mod5.x = 1;
////mod6.x = 1;
// @Filename: b.ts
////module "global-ambient-module" {}
goTo.file("a.ts")
const diagnostics = test.ranges().map(range => ({
code: 1540,
message: "A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.",
reportsDeprecated: true as true,
range,
}));
verify.getSuggestionDiagnostics(diagnostics)
goTo.file("b.ts")
verify.getSuggestionDiagnostics([])