-
Notifications
You must be signed in to change notification settings - Fork 1.1k
support quick info and go to definition on mapped keys #3264
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
base: main
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package fourslash_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/microsoft/typescript-go/internal/fourslash" | ||
| "github.com/microsoft/typescript-go/internal/testutil" | ||
| ) | ||
|
|
||
| func TestGoToDefinitionMappedType2(t *testing.T) { | ||
| t.Parallel() | ||
| defer testutil.RecoverAndFail(t, "Panic on fourslash test") | ||
| const content = `interface Foo { | ||
| /*def*/property: string | ||
| } | ||
|
|
||
| type JustMapIt<T> = {[P in keyof T]: 0} | ||
| type MapItWithRemap<T> = {[P in keyof T as P extends string ? ` + "`mapped_${P}`" + ` : never]: 0} | ||
|
|
||
| { | ||
| let gotoDef!: JustMapIt<Foo> | ||
| gotoDef.property | ||
| } | ||
|
|
||
| { | ||
| let gotoDef!: MapItWithRemap<Foo> | ||
| gotoDef.[|/*ref*/mapped_property|] | ||
| }` | ||
| f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) | ||
| defer done() | ||
| f.VerifyBaselineGoToDefinition(t, true, "ref") | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package fourslash_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/microsoft/typescript-go/internal/fourslash" | ||
| "github.com/microsoft/typescript-go/internal/testutil" | ||
| ) | ||
|
|
||
| func TestGoToDefinitionMappedType3(t *testing.T) { | ||
| t.Parallel() | ||
| defer testutil.RecoverAndFail(t, "Panic on fourslash test") | ||
| const content = `interface Source { | ||
| /*def*/alpha: number; | ||
| beta: string; | ||
| } | ||
|
|
||
| // Transforming interface field names with a suffix | ||
| type Transformed<T> = { | ||
| [K in keyof T as ` + "`${K & string}Suffix`" + `]: () => T[K]; | ||
| }; | ||
|
|
||
| type Result = Transformed<Source>; | ||
| /* | ||
| Expected: | ||
| { | ||
| alphaSuffix: () => number; | ||
| betaSuffix: () => string; | ||
| } | ||
| */ | ||
|
|
||
| const obj: Result = { | ||
| alphaSuffix: () => 42, | ||
| betaSuffix: () => "hello", | ||
| }; | ||
|
|
||
| obj.[|/*ref*/alphaSuffix|]();` | ||
| f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) | ||
| defer done() | ||
| f.VerifyBaselineGoToDefinition(t, true, "ref") | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package fourslash_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/microsoft/typescript-go/internal/fourslash" | ||
| "github.com/microsoft/typescript-go/internal/testutil" | ||
| ) | ||
|
|
||
| func TestQuickInfoMappedType2(t *testing.T) { | ||
| t.Parallel() | ||
| defer testutil.RecoverAndFail(t, "Panic on fourslash test") | ||
| // Tests that @inheritDoc on a MappedTypeNode causes hover to show documentation. | ||
| // TODO: once @inheritDoc resolution is fully implemented, the expected documentation | ||
| // should be "desc on Getters\nhello" (combined from the mapped type and the source property). | ||
| const content = `type ToGet<T> = T extends string ? ` + "`get${Capitalize<T>}`" + ` : never; | ||
| type Getters<T> = /** @inheritDoc desc on Getters */ { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you also add a quick info case without property remapping? |
||
| [P in keyof T as ToGet<P>]: () => T[P] | ||
| }; | ||
|
|
||
| type Y = { | ||
| /** hello */ | ||
| d: string; | ||
| } | ||
|
|
||
| type T50 = Getters<Y>; | ||
|
|
||
| declare let y: T50; | ||
| y.get/*3*/D;` | ||
| f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) | ||
| defer done() | ||
| // Current Go behavior: shows the raw @inheritDoc tag text from the mapped type declaration. | ||
| f.VerifyQuickInfoAt(t, "3", "(property) getD: () => string", "\n\n*@inheritDoc* \u2014 desc on Getters ") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the default behavior will be to not inherit the jsdoc from e.g.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if it makes sense to also port |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package fourslash_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/microsoft/typescript-go/internal/fourslash" | ||
| "github.com/microsoft/typescript-go/internal/testutil" | ||
| ) | ||
|
|
||
| func TestQuickInfoMappedType3(t *testing.T) { | ||
| t.Parallel() | ||
| defer testutil.RecoverAndFail(t, "Panic on fourslash test") | ||
| const content = `type Getters<Type> = /** @inheritDoc desc on Getters */ { | ||
| [Property in keyof Type as ` + "`" + `get${Capitalize< | ||
| string & Property | ||
| >}` + "`" + `]: () => Type[Property]; | ||
| }; | ||
|
|
||
| interface Person { | ||
| // ✅ When hovering here, the documentation is displayed, as it should. | ||
|
||
| /** | ||
| * Person's name. | ||
| * @example "John Doe" | ||
| */ | ||
| name: string; | ||
|
|
||
| // ✅ When hovering here, the documentation is displayed, as it should. | ||
| /** | ||
| * Person's Age. | ||
| * @example 30 | ||
| */ | ||
| age: number; | ||
|
|
||
| // ✅ When hovering here, the documentation is displayed, as it should. | ||
| /** | ||
| * Person's Location. | ||
| * @example "Brazil" | ||
| */ | ||
| location: string; | ||
| } | ||
|
|
||
| type LazyPerson = Getters<Person>; | ||
|
|
||
| const me: LazyPerson = { | ||
| // ✅ When hovering here, the documentation is displayed, as it should. | ||
| /*1*/getName: () => "Jake Carter", | ||
| // ✅ When hovering here, the documentation is displayed, as it should. | ||
| /*2*/getAge: () => 35, | ||
| // ✅ When hovering here, the documentation is displayed, as it should. | ||
| /*3*/getLocation: () => "United States", | ||
| }; | ||
|
|
||
| // ✅ When hovering here, the documentation is displayed, as it should. | ||
| me./*4*/getName();` | ||
| f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) | ||
| defer done() | ||
| f.VerifyBaselineHover(t) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package fourslash_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/microsoft/typescript-go/internal/fourslash" | ||
| "github.com/microsoft/typescript-go/internal/testutil" | ||
| ) | ||
|
|
||
| func TestQuickInfoMappedType4(t *testing.T) { | ||
| t.Parallel() | ||
| defer testutil.RecoverAndFail(t, "Panic on fourslash test") | ||
| const content = `type ToGet<T> = T extends string ? ` + "`get${Capitalize<T>}`" + ` : never; | ||
| type Getters<T> = { | ||
| /** @inheritDoc desc on Getters */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why doesn't this work but adding the comment outside the mapped type work? |
||
| [P in keyof T as ToGet<P>]: () => T[P] | ||
|
|
||
| }; | ||
|
|
||
| type Y = { | ||
| /** hello */ | ||
| d: string; | ||
| } | ||
|
|
||
| type T50 = Getters<Y>; | ||
|
|
||
| declare let y: T50; | ||
| y.get/*3*/D;` | ||
| f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) | ||
| defer done() | ||
| f.VerifyQuickInfoAt(t, "3", "(property) getD: () => string", "") | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // === goToDefinition === | ||
| // === /goToDefinitionMappedType2.ts === | ||
| // interface Foo { | ||
| // <|[|property|]: string|> | ||
| // } | ||
| // | ||
| // type JustMapIt<T> = {[P in keyof T]: 0} | ||
| // --- (line: 6) skipped --- | ||
|
|
||
| // --- (line: 11) skipped --- | ||
| // | ||
| // { | ||
| // let gotoDef!: MapItWithRemap<Foo> | ||
| // gotoDef./*GOTO DEF*/mapped_property | ||
| // } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // === goToDefinition === | ||
| // === /goToDefinitionMappedType3.ts === | ||
| // interface Source { | ||
| // <|[|alpha|]: number;|> | ||
| // beta: string; | ||
| // } | ||
| // | ||
| // --- (line: 6) skipped --- | ||
|
|
||
| // --- (line: 21) skipped --- | ||
| // betaSuffix: () => "hello", | ||
| // }; | ||
| // | ||
| // obj./*GOTO DEF*/alphaSuffix(); |
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.
Did you mean to also test the simpler case here?