-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Fix/indexed access type hover #62677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
0d0bd10
dce4663
9eb59a8
07ea18b
729c75a
07d33dc
134ed3c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6842,7 +6842,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | |||||||||
| return factory.createThisTypeNode(); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| if (!inTypeAlias && type.aliasSymbol && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) { | ||||||||||
| // When in an object type literal context, expand type aliases to show resolved types | ||||||||||
| // for better clarity in hover information and quick info | ||||||||||
| if (!inTypeAlias && type.aliasSymbol && !(context.flags & NodeBuilderFlags.InObjectTypeLiteral) && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) { | ||||||||||
| if (!shouldExpandType(type, context, /*isAlias*/ true)) { | ||||||||||
| const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); | ||||||||||
| if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & SymbolFlags.Class)) return factory.createTypeReferenceNode(factory.createIdentifier(""), typeArgumentNodes); | ||||||||||
|
|
@@ -9028,7 +9030,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | |||||||||
| let result; | ||||||||||
| const addUndefinedForParameter = declaration && (isParameter(declaration) || isJSDocParameterTag(declaration)) && requiresAddingImplicitUndefined(declaration, context.enclosingDeclaration); | ||||||||||
| const decl = declaration ?? symbol.valueDeclaration ?? getDeclarationWithTypeAnnotation(symbol) ?? symbol.declarations?.[0]; | ||||||||||
| if (!canPossiblyExpandType(type, context) && decl) { | ||||||||||
| // When in an object type literal context, prefer the resolved type over the syntactic form | ||||||||||
| // to ensure indexed access types and generic type aliases are properly resolved | ||||||||||
|
||||||||||
| // When in an object type literal context, prefer the resolved type over the syntactic form | |
| // to ensure indexed access types and generic type aliases are properly resolved | |
| // When NOT in an object type literal context, prefer the syntactic form over the resolved type | |
| // to preserve original type annotations where possible |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| /// <reference path='fourslash.ts'/> | ||
|
|
||
| // @strict: true | ||
|
|
||
| // @Filename: /test.ts | ||
| ////type Scalars = { | ||
| //// Number: number; | ||
| ////}; | ||
| //// | ||
| ////type Maybe<T> = T | null; | ||
| //// | ||
| ////type TypeA = { | ||
| //// a: Scalars["Number"] | null; | ||
| //// b: Maybe<number>; | ||
| //// c: Scalars["Number"] | null; | ||
| ////}; | ||
| //// | ||
| ////type TypeB = { | ||
| //// a: Scalars["Number"] | null; | ||
| //// b: number | null; | ||
| //// c: Scalars["Number"] | null; | ||
| ////}; | ||
| //// | ||
| ////const testA: Type/*typeA*/A = null!; | ||
| ////const testB: Type/*typeB*/B = null!; | ||
|
|
||
| // Both types should show fully resolved types (number | null) for all fields | ||
| goTo.marker("typeA"); | ||
| verify.quickInfoIs(`type TypeA = { | ||
| a: number | null; | ||
| b: number | null; | ||
| c: number | null; | ||
| }`); | ||
|
|
||
| goTo.marker("typeB"); | ||
| verify.quickInfoIs(`type TypeB = { | ||
| a: number | null; | ||
| b: number | null; | ||
| c: number | null; | ||
| }`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment describes expanding type aliases but the actual condition checks for
!(context.flags & NodeBuilderFlags.InObjectTypeLiteral)which means the expansion is avoided when in object type literal context. The comment should clarify that type aliases are expanded unless we're in an object type literal context, or the logic may be inverted from the intended behavior.