From 27eecbcfba597aa6b61e28dee365f677bfa70104 Mon Sep 17 00:00:00 2001 From: Tanzim Hossain Romel Date: Wed, 17 Dec 2025 00:29:47 +0600 Subject: [PATCH] Support @deprecated on namespace aliases (ImportEqualsDeclaration) Fixes #62340 When a namespace re-exports a type using `export import Bar = example.Bar` with a `@deprecated` JSDoc comment, the deprecation warning was not being reported when accessing `JSX.Bar` as a type. The issue was that in `checkTypeReferenceOrImport`, the `resolvedSymbol` is the resolved target of the alias, not the alias itself. To detect deprecation on the alias, we now also resolve the entity name without resolving aliases and check if the alias symbol itself is deprecated. --- src/compiler/checker.ts | 16 +++++++ .../jsdocDeprecated_namespaceAlias.ts | 46 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 tests/cases/fourslash/jsdocDeprecated_namespaceAlias.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8c52e9d172877..ce60fe5ca4deb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -42740,6 +42740,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ); } } + // Also check if the type reference is an alias that is deprecated (e.g., ImportEqualsDeclaration with @deprecated) + if (node.kind !== SyntaxKind.ImportType) { + const name = getTypeReferenceName(node as TypeReferenceType); + if (name) { + const aliasSymbol = resolveEntityName(name, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ true); + if (aliasSymbol && aliasSymbol !== unknownSymbol && aliasSymbol !== symbol && aliasSymbol.flags & SymbolFlags.Alias) { + if (isDeprecatedSymbol(aliasSymbol) && aliasSymbol.declarations) { + addDeprecatedSuggestion( + getDeprecatedSuggestionNode(node), + aliasSymbol.declarations, + aliasSymbol.escapedName as string, + ); + } + } + } + } } } diff --git a/tests/cases/fourslash/jsdocDeprecated_namespaceAlias.ts b/tests/cases/fourslash/jsdocDeprecated_namespaceAlias.ts new file mode 100644 index 0000000000000..88a991cec3869 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_namespaceAlias.ts @@ -0,0 +1,46 @@ +/// + +// @Filename: /example.ts +//// export type Bar = string | number; +//// /** @deprecated */ +//// export type Baz = string | number; + +// @Filename: /foo.ts +//// import * as example from './example'; +//// +//// export namespace JSX { +//// /** @deprecated */ +//// export type Foo = string | number; +//// +//// /** @deprecated */ +//// export import Bar = example.Bar; +//// +//// export import Baz = example.Baz; +//// } +//// +//// export type X = JSX.[|Foo|]; // Should be deprecated (Foo itself is deprecated) +//// export type Y = JSX.[|Bar|]; // Should be deprecated (Bar alias is deprecated) +//// export type Z = JSX.[|Baz|]; // Should be deprecated (example.Baz is deprecated) + +goTo.file('/foo.ts'); +const ranges = test.ranges(); +verify.getSuggestionDiagnostics([ + { + "message": "'Foo' is deprecated.", + "code": 6385, + "range": ranges[0], + "reportsDeprecated": true, + }, + { + "message": "'Bar' is deprecated.", + "code": 6385, + "range": ranges[1], + "reportsDeprecated": true, + }, + { + "message": "'Baz' is deprecated.", + "code": 6385, + "range": ranges[2], + "reportsDeprecated": true, + }, +]);