Use `origin` for string literal definitions

This commit is contained in:
Mateusz Burzyński 2024-03-12 00:07:12 +01:00
Родитель e24d886305
Коммит 9e55b0ce57
5 изменённых файлов: 54 добавлений и 0 удалений

Просмотреть файл

@ -1664,6 +1664,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
getResolvedSignature: (node, candidatesOutArray, argumentCount) => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.Normal),
getCandidateSignaturesForStringLiteralCompletions,
getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, argumentCount) => runWithoutResolvedSignatureCaching(node, () => getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, CheckMode.IsForSignatureHelp)),
getContextualOriginTypeForStringDefinition: (node: StringLiteralLike) => {
const contextualType = getContextualType(node, /*contextFlags*/ undefined);
return contextualType && contextualType.flags & TypeFlags.Union ? (contextualType as UnionType).origin : undefined;
},
getExpandedParameters,
hasEffectiveRestParameter,
containsArgumentsReference,

Просмотреть файл

@ -4967,6 +4967,7 @@ export interface TypeChecker {
/** @internal */ getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined;
/** @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type | undefined;
/** @internal */ getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined;
/** @internal */ getContextualOriginTypeForStringDefinition(node: StringLiteralLike): Type | undefined;
/** @internal */ isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean;
/** @internal */ getTypeOfPropertyOfContextualType(type: Type, name: __String): Type | undefined;

Просмотреть файл

@ -69,6 +69,7 @@ import {
isPropertyName,
isRightSideOfPropertyAccess,
isStaticModifier,
isStringLiteralLike,
isSwitchStatement,
isTypeAliasDeclaration,
isTypeReferenceNode,
@ -186,6 +187,16 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
});
}
if (isStringLiteralLike(node)) {
const contextualOriginType = typeChecker.getContextualOriginTypeForStringDefinition(node);
if (contextualOriginType?.isIndexType() && !contextualOriginType.type.isUnion()) {
const symbol = contextualOriginType.type.getProperty(node.text);
if (symbol) {
return getDefinitionFromSymbol(typeChecker, symbol, node);
}
}
}
let { symbol, failedAliasResolution } = getSymbol(node, typeChecker, stopAtAlias);
let fallbackNode = node;

Просмотреть файл

@ -0,0 +1,24 @@
// === goToDefinition ===
// === /tests/cases/fourslash/goToDefinitionStringLiteral1.ts ===
// type User = {
// <|[|name|]: string;|>
// age: number;
// };
//
// declare function fn<T>(obj: T, key: keyof T): void;
//
// declare const user: User;
//
// fn(user, "name/*GOTO DEF*/");
// === Details ===
[
{
"kind": "property",
"name": "name",
"containerName": "__type",
"isLocal": false,
"isAmbient": false,
"unverified": false
}
]

Просмотреть файл

@ -0,0 +1,14 @@
/// <reference path='fourslash.ts'/>
//// type User = {
//// name: string;
//// age: number;
//// };
////
//// declare function fn<T>(obj: T, key: keyof T): void;
////
//// declare const user: User;
////
//// fn(user, "name/*1*/");
verify.baselineGoToDefinition("1");