For { type: "a" } | { type: "b" }, find references for the union property (#21298)

This commit is contained in:
Andy 2018-01-19 16:04:30 -08:00 committed by GitHub
parent eed85737b8
commit 6224d51f84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 3 deletions

View File

@ -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<SourceFile>, 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;
}
/**

View File

@ -0,0 +1,16 @@
/// <reference path='fourslash.ts'/>
////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] },
]);