Skip to content
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

with infer in template string, suggestion works in 4.6, but not work in 4.7 #49680

Closed
xxleyi opened this issue Jun 25, 2022 · 7 comments Β· Fixed by #54121
Closed

with infer in template string, suggestion works in 4.6, but not work in 4.7 #49680

xxleyi opened this issue Jun 25, 2022 · 7 comments Β· Fixed by #54121
Assignees
Labels
Fix Available A PR has been opened for this issue Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@xxleyi
Copy link

xxleyi commented Jun 25, 2022

Bug Report

πŸ”Ž Search Terms

suggestion pathof

πŸ•— Version & Regression Information

4.7

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// get from https://github.com/microsoft/TypeScript/issues/20423#issuecomment-812564842
type PathOf<T, K extends string, P extends string = ""> =
  K extends `${infer U}.${infer V}`
    ? U extends keyof T ? PathOf<T[U], V, `${P}${U}.`> : `${P}${keyof T & (string | number)}`
    : K extends keyof T ? `${P}${K}` : `${P}${keyof T & (string | number)}`;


declare function consumer<K extends string>(path: PathOf<{a: string, b: {c: string}}, K>) : number;

// suggestion works well in 4.6, and not work in 4.7
consumer('b.')

πŸ™ Actual behavior

image

πŸ™‚ Expected behavior

image

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jun 30, 2022
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.8.1 milestone Jun 30, 2022
@rbuckton
Copy link
Member

This doesn't seem to be due to infer, but instead is a direct result of the changes in #48410. @andrewbranch, is this an intended consequence of that change? Prior to this change (or if I skip the call to runWithInferenceBlockedFromSourceNode), we instantiate K with the string literal type "b.". However, with runWithInferenceBlockedFromSourceNode we instead end up instantiating K with string.

@rbuckton
Copy link
Member

Note that we have no suggestions in 4.7.4 for "b." because the suggestion list we return includes "a" and "b", and "b." has essentially already filtered out the possible suggestions.

@andrewbranch
Copy link
Member

No, not intended. The nonlinearity of conditional types makes it impossible to guess with any certainty whether a wider or narrower instantiation is going to produce better completions... maybe we ought to do both and concatenate the results.

@dmitri-gb
Copy link
Contributor

We have also come across a somewhat similar case where the list of suggestions in TS 4.7 (and 4.8) is no longer the same as it was in TS 4.6.

declare function pick<T extends object, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K>;

const obj = { aaa: 1, bbb: '2', ccc: true };

pick(obj, 'aaa', ''); // suggestions inside the empty string
                      // TS 4.6: aaa, bbb, ccc
                      // TS 4.7: aaa

Playground link

It is worth noting that if I rewrite pick and make keys a proper array instead of a rest parameter, then the list of suggestions will include all the properties just as in TS 4.6.

Another way to get around the issue is to use a slightly different definition for pick:

declare function pick<T extends object, K extends (keyof T)[]>(obj: T, ...keys: K): Pick<T, K[number]>;

It's unfortunate that the (seemingly) more natural definition of pick looses its ability to provide useful suggestions. I'm curious if this is something that the TS team would consider a regression and try to revert, or is this how we should expect things to work from now on?

@wwwouter
Copy link

wwwouter commented Oct 10, 2022

I'm experiencing the same thing. It worked with 4.6.x, and it still works with 4.9.0-dev.20221007 and 4.8.1-rc

4.6.4

image

4.7.4:

image

It compiles fine with "id" as second argument with both versions, it seems to be the language server that is acting up.

@RyanCavanaugh RyanCavanaugh added the Rescheduled This issue was previously scheduled to an earlier milestone label Feb 1, 2023
@itsUndefined
Copy link

Can this task get a higher priority?

@Andarist
Copy link
Contributor

@dmitri-gb's and @wwwouter's cases are somewhat different from the OP. The problem with those 2 is that the type param is being used as rest but only the "current" argument is being "blocked". If all arguments typed through this rest would get blocked then it would work OK. At the same time... it's not that hard to imagine that a different piece within a given call could fix the inference in a similar way, so fixing this specific case by blocking sibling arguments that are typed through the same rest wouldn't necessarily fix the whole issue. OTOH, this particular use case is probably more common than those other cases so perhaps it would still be worth exploring this as a solution right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Available A PR has been opened for this issue Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone
Projects
None yet
9 participants