diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 8b7473357fe63..ee586d593f7fd 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -356,7 +356,7 @@ namespace ts.FindAllReferences.Core { /** Core find-all-references algorithm for a normal symbol. */ function getReferencedSymbolsForSymbol(symbol: Symbol, node: Node, sourceFiles: ReadonlyArray, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] { - symbol = skipPastExportOrImportSpecifier(symbol, node, checker); + symbol = skipPastExportOrImportSpecifierOrUnion(symbol, node, checker); // Compute the meaning from the location and the symbol it references const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.declarations); @@ -405,7 +405,7 @@ namespace ts.FindAllReferences.Core { } /** Handle a few special cases relating to export/import specifiers. */ - function skipPastExportOrImportSpecifier(symbol: Symbol, node: Node, checker: TypeChecker): Symbol { + function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker): Symbol { const { parent } = node; if (isExportSpecifier(parent)) { return getLocalSymbolForExportSpecifier(node as Identifier, symbol, parent, checker); @@ -415,7 +415,11 @@ namespace ts.FindAllReferences.Core { return checker.getImmediateAliasedSymbol(symbol); } - return symbol; + // If the symbol is declared as part of a declaration like `{ type: "a" } | { type: "b" }`, use the property on the union type to get more references. + return firstDefined(symbol.declarations, decl => + isTypeLiteralNode(decl.parent) && isUnionTypeNode(decl.parent.parent) + ? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name) + : undefined) || symbol; } /** diff --git a/tests/cases/fourslash/findAllRefsUnionProperty.ts b/tests/cases/fourslash/findAllRefsUnionProperty.ts new file mode 100644 index 0000000000000..ddbfd54144fe2 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsUnionProperty.ts @@ -0,0 +1,16 @@ +/// + +////type T = +//// | { [|{| "isWriteAccess": true, "isDefinition": true |}type|]: "a" } +//// | { [|{| "isWriteAccess": true, "isDefinition": true |}type|]: "b" }; +////declare const t: T; +////if (t.[|type|] !== "failure") { +//// t.[|type|]; +////} + +const ranges = test.ranges(); +const [r0, r1, r2, r3] = ranges; +verify.referenceGroups(ranges, [ + { definition: '(property) type: "a"', ranges: [r0, r2, r3] }, // TODO: this have type `"a" | "b"` + { definition: '(property) type: "b"', ranges: [r1] }, +]);