From d27d2ac80525bb2d21e864a8b9b5e4abae11e940 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 7 Nov 2024 23:26:43 +0200 Subject: [PATCH] feat(60442): show deprecation warnings on implementations of a deprecated property --- src/compiler/checker.ts | 12 ++++++++ .../fourslash/jsdocDeprecated_suggestion19.ts | 11 +++++-- .../fourslash/jsdocDeprecated_suggestion23.ts | 29 +++++++++++++++++++ .../fourslash/jsdocDeprecated_suggestion24.ts | 21 ++++++++++++++ .../fourslash/jsdocDeprecated_suggestion25.ts | 21 ++++++++++++++ 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/jsdocDeprecated_suggestion23.ts create mode 100644 tests/cases/fourslash/jsdocDeprecated_suggestion24.ts create mode 100644 tests/cases/fourslash/jsdocDeprecated_suggestion25.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 88c71bbfdf088..051f0c753b49d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32758,6 +32758,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { member = prop; allPropertiesTable?.set(prop.escapedName, prop); + if (contextualType) { + forEach(getPropertyOfType(contextualType, member.escapedName)?.declarations, declaration => { + const symbol = getSymbolOfDeclaration(declaration); + if ( + isDeprecatedSymbol(symbol) && symbol.declarations && + isTypeAssignableTo(type, getTypeOfSymbol(symbol)) + ) { + addDeprecatedSuggestion(memberDecl.name, symbol.declarations, member.escapedName as string); + } + }); + } + if ( contextualType && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && (memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.MethodDeclaration) && isContextSensitive(memberDecl) diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion19.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion19.ts index f70ae4b9b923f..6685eb5b64662 100644 --- a/tests/cases/fourslash/jsdocDeprecated_suggestion19.ts +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion19.ts @@ -8,15 +8,20 @@ //// /** @deprecated */ //// x: number; ////} -////const foo: I = { x: 1, y: 1 }; +////const foo: I = { [|x|]: 1, y: 1 }; ////foo.[|x|]; -const [range] = test.ranges(); verify.getSuggestionDiagnostics([ { "code": 6385, "message": "'x' is deprecated.", "reportsDeprecated": true, - "range": range + "range": test.ranges()[0] + }, + { + "code": 6385, + "message": "'x' is deprecated.", + "reportsDeprecated": true, + "range": test.ranges()[1] }, ]); diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion23.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion23.ts new file mode 100644 index 0000000000000..99ec16f188edd --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion23.ts @@ -0,0 +1,29 @@ +/// + +// @filename: /a.ts +////type I = { +//// /** +//// * @deprecated +//// */ +//// text: string; +////} | { +//// text: { a: string; b: string }; +////}; +//// +////const a: I = { [|text|]: "" }; +////a.[|text|]; + +verify.getSuggestionDiagnostics([ + { + code: 6385, + message: "'text' is deprecated.", + reportsDeprecated: true, + range: test.ranges()[0] + }, + { + code: 6385, + message: "'text' is deprecated.", + reportsDeprecated: true, + range: test.ranges()[1] + }, +]); diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion24.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion24.ts new file mode 100644 index 0000000000000..681a45a4f2910 --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion24.ts @@ -0,0 +1,21 @@ +/// + +// @filename: /a.ts +////type I = { +//// /** +//// * @deprecated +//// */ +//// text: string; +////}; +//// +////function f(i: I) { return i; } +////f({ [|text|]: 'a' }); + +verify.getSuggestionDiagnostics([ + { + code: 6385, + message: "'text' is deprecated.", + reportsDeprecated: true, + range: test.ranges()[0] + }, +]); diff --git a/tests/cases/fourslash/jsdocDeprecated_suggestion25.ts b/tests/cases/fourslash/jsdocDeprecated_suggestion25.ts new file mode 100644 index 0000000000000..d6eb02e239faa --- /dev/null +++ b/tests/cases/fourslash/jsdocDeprecated_suggestion25.ts @@ -0,0 +1,21 @@ +/// + +// @filename: /a.ts +////interface A { +//// a: number; +////} +////interface B { +//// /** @deprecated */ +//// a: string; +////} +////const a: A | B = { [|a|]: 'a' } +////const b: A | B = { [|a|]: 1 } + +verify.getSuggestionDiagnostics([ + { + code: 6385, + message: "'a' is deprecated.", + reportsDeprecated: true, + range: test.ranges()[0], + }, +]);