Repository navigation
Closed as not planned
Closed as not planned
Copy link
Labels
7.0 LS MigrationBugA bug in TypeScriptA bug in TypeScriptDomain: LS: Completion ListsThe issue relates to showing completion lists in an editorThe issue relates to showing completion lists in an editor
Milestone
Description
Bug Report
Optional properties in inferred mapped type causes auto-completion to break.
π Search Terms
Inferred mapped type with optional properties no auto-complete
π Version & Regression Information
I believe it never worked.
β― Playground Link
π» Code
type A1<T extends object> = {
[K in (keyof T | 'autoCompleteProp')]:
K extends 'autoCompleteProp'
? boolean
: K extends keyof T
? T[K] extends object
? A1<T[K]>
: object
: never;
}
type A2<T extends object> = {
[K in (keyof T | 'autoCompleteProp')]?: // <---- this is the only difference compared to A1
K extends 'autoCompleteProp'
? boolean
: K extends keyof T
? T[K] extends object
? A2<T[K]>
: object
: never;
}
function makeA1<T extends A1<T>>(t: T) {
return t;
}
function makeA2<T extends A2<T>>(t: T) {
return t;
}
makeA1({
autoCompleteProp: true, // <-- you CAN autoComplete 'autoCompleteProp' here
bla: {
autoCompleteProp: true, // <-- you CAN autoComplete 'autoCompleteProp' here
blubb: {
autoCompleteProp: false, // <-- you CAN autoComplete 'autoCompleteProp' here
bleh: {
// <-- you CAN autoComplete 'autoCompleteProp' here
}
},
},
});
makeA2({
autoCompleteProp: true, // <-- you CAN autoComplete 'autoCompleteProp' here
bla: {
// <-- you CAN'T autoComplete 'autoCompleteProp' here
blubb: {
// <-- you CAN'T autoComplete 'autoCompleteProp' here
bleh: {
// <-- you CAN'T autoComplete 'autoCompleteProp' here
},
},
},
});π Actual behavior
No auto-completion offered by editor or IDE in marked lines when pressing CTRL + SPACE or a
Edit: You can enter autoCompleteProp: '', in the lines where auto-completion fails. The compiler will complain that autoCompleteProp must be a boolean. Thus, the information about the optional property is there, it's just that it never appears in the auto-completion results.
π Expected behavior
Auto-complete suggestion for "autoCompleteProp" in every line marked with <--
Reacted by Sadegh Barati, Vitaly, Denis Pshenov, Nick Worrall, mrmntte and Victor Garcia
Reacted by Sadegh Barati, mrmntte and Victor Garcia
Metadata
Metadata
Assignees
Labels
7.0 LS MigrationBugA bug in TypeScriptA bug in TypeScriptDomain: LS: Completion ListsThe issue relates to showing completion lists in an editorThe issue relates to showing completion lists in an editor
Activity
Andarist commentedon Jun 27, 2022
I think this has bitten me in the past and it would be lovely to get this fixed.
So far this is what I've gathered:
inferredType(eg:{ autoCompleteProp: true; someProp: {}; }) doesn't pass thecompareTypescheck and thus theinstantiatedConstraint(A1<{ autoCompleteProp: true; someProp: {}; }>) gets assigned toinference.inferredTypeinferredType({ autoCompleteProp: true; someProp: {}; }) passes thecompareTypescheck and thusinferredTypestays assigned toinference.inferredTypeas-is.compareTypescheck is simply usingcompareTypesAssignableunder the hood so the logic here makes sense - with optional members theinferredTypeis assignable to theinstantiatedConstraintbut with required ones it isn't.getCompletionsAtPositionends up looking up properties of thisinferredTypeand it fails to seeautoCompletePropthere because the inference "locked" the type param to an object without this propertyPart of the question here is - should this
autoCompleteProp?: booleanbe part of the inferred type? If we assume thatmakeA1/makeA2are really identity functions - should this property be available on the returned object? I guess the choice here is somewhat arbitrary and there is no good/bad answer here. A decision had to be made about this and it's not part of that type.That raises an issue with the autocomplete though. I knew about some other, somewhat similar, issues with "locked" inferences - eg. this PR by Andrew Branch (@andrewbranch). So I've thought that maybe a similar approach could be taken here. We could avoid "locking" the inference when resolving those types for the completions "request" .
I've experimented with this a little bit and, while I broke some stuff, I think I also got somewhat promising results here. I learned that it's definitely not as easy as just using
instantiatedConstraintoverinferredTypeπHowever, the problem I see with this is that the mentioned
compareTypesis concerned with type params/arguments but what I would truly like to do is to avoid locking the inference for the object at a given position, a mapped type like this can be nested somewhere in the parameter and doesn't have to appear "at the top-level" of the parameter. Does anyone have any ideas how to approach this?barak007 commentedon Dec 17, 2023
I hope this gets fixed soon.
I have a simple case similar to this and I think the offender here is the combination of extending
Partialandkeyof T.it also sounds similar to #45617
Playground
victorgarciaesgi commentedon Apr 1, 2025
Hey! In Typescript
5.8.xthis is still happening, despite the #48410 that was merged.Here is a reproduction
RyanCavanaugh commentedon Dec 3, 2025
Closing language service bugs related to the 6.0 implementation. For more information, see #62827