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

type inference issue with dynamic template literals #58402

Open
playerx opened this issue May 2, 2024 · 2 comments
Open

type inference issue with dynamic template literals #58402

playerx opened this issue May 2, 2024 · 2 comments
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Milestone

Comments

@playerx
Copy link

playerx commented May 2, 2024

πŸ”Ž Search Terms

"template literals and type inference", "type inference with dynamic template literals"

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about it

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.4.5#code/C4TwDgpgBAgmCWUC8UDeAoKUDaBrCIAXFAAYAWEANpQPYB0AJKgM7ABO8AdgOYC+JAXWIAKACYBDYOOKooncQFsIxVhx5ReASmQA+KADca8Uel7p0lCMCgBXZhDYBJUSvZduyKAHJRIeQvgAYyhVdy9zAHoIqABRAA9FMEsARmIAERoIZk4vawB3GjZcOihQSCgAM0LSCBIoQPEc6wAjaC4KhzYIE0CaTlZSrOBU2ARPDCxscipaRlQ7B2d+IShoJD0JrHq+5hpLOlpuYQg6fwhNTA0AGlNI6PjEywAmYgB1QtxmdF7+62Ahl6jRAoTZTCjUeisSRBAD6oR4gmIaw2lywP12+0Ox1OinOl14NzM6CisQSCiSEAAzG8Pl90dY+p4ADwAaVWcX+nFEzCg+BANAqQJ0wkufOILJuWHEgWA8D6IgkUmIcHg2BZAm06wMRlEN01KKwJN2SighyCt3QfWE0whcwWTlE-Cuq10aEu6L2JyxJzOFy0QA

πŸ’» Code

type Api = {
  [key: `hello.${string}`]: (data: { name: string }) => void
}

let userId: string = 'dynamic string'

// Example1: Doesn't work. type for `e` can't be inferred
const test1: Api = {
  [`hello.${userId}`]: e => {
    console.log(e.name)
  },
}

// Example2: Works
const test2: Api = {
  [`hello.static_string`]: e => {
    console.log(e.name)
  },
}

// Example3: Works
const on = <K extends keyof Api>(
  key: K,
  action: (data: Api[K]) => void,
) => {
  // some logic
}

on(`hello.${userId}`, e => {
  console.log(e.name)
})

πŸ™ Actual behavior

Example 1 doesn't work, while Example 2 and Example 3 works properly. The type for e can't be inferred

πŸ™‚ Expected behavior

To infer type of e in the Example 1.

Additional information about the issue

No response

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases labels May 2, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone May 2, 2024
@Andarist
Copy link
Contributor

Andarist commented May 3, 2024

In a sense, this could be seen as a duplicate of #13948 . Like I mentioned here the computed properties like this are always widened - without considering the contextual property keys.

A somewhat related thing to this is that those assignments work because index signatures turn off common property checking:

const obj: { [key: `hello.${string}`]: string } = {} as {
  [key: string]: string;
};

This is OK but it would - IMHO - make sense for this to participate in the common property check. You can see a different issue related to this: #55709

@Xriuk
Copy link

Xriuk commented May 17, 2024

Not sure if it's related to this but I'm facing a similar problem:

type Original = `/AnyString/${number}`;
type Match = Original extends `${infer Head}/${number}${infer Tail}` ? {
    a: Head,
    b: Tail
} : never;

Here Match is never because apparently it matches /AnyString as /${number} and then fails because AnyString is not a number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Projects
None yet
Development

No branches or pull requests

4 participants