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

Template literal value not assignable to template literal type #56659

Closed
patrick-bricout-spendesk opened this issue Dec 4, 2023 · 3 comments · Fixed by #55371
Closed

Template literal value not assignable to template literal type #56659

patrick-bricout-spendesk opened this issue Dec 4, 2023 · 3 comments · Fixed by #55371
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@patrick-bricout-spendesk
Copy link

patrick-bricout-spendesk commented Dec 4, 2023

🔎 Search Terms

template literal not assignable

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Common "Bugs" That Aren't Bugs
  • There is an error since version 4.1.5 (I think this is when template literal types have been introduced)

⏯ Playground Link

https://www.typescriptlang.org/play?#code/C4TwDgpgBAShDmBLAzsATiKBeKBvAUFEVAIYBcepAjBbgL5R2HEBGtULNeDTT+okKAGkIIAPYAzADwAVAHzYoAa1GSoMqADIoqNIgB28fPgkBXfQGNgiMfqgSqU5kQDKFsYIgAPYBH0ATZGFVaTgkXRA5ABpnKABRADc-YChvXwCgkXFQhBR0EABtNw8IAF05fDkACggk-WAABRJgAAsKAAMAElxiyDoybsTkunaASjxY931UKALkd0go1LrgUsVa5KbWgDpkMAAbRGAqgCIyE9HJ22QxfYht-bF4KvmSpY36y74zS2tbewATE5iFBetA0n5AsFslIwnkMNFYkN6qkfJDMiFYbkIkUFmUKtVXpAKGD3isKMjgOMCCCHFUurgiRB+t0PsARl98EA

💻 Code

type Registry = {
    a: { a1: {} }
    b: { b1: {} }
}

type Keyof<T> = keyof T & string

function f1<
    Scope extends Keyof<Registry>,
    Event extends Keyof<Registry[Scope]>
>(eventPath: `${Scope}:${Event}`) {
    const [scope, event] = eventPath.split(":")
    console.log(scope, event)
}

function f2<
    Scope extends Keyof<Registry>,
    Event extends Keyof<Registry[Scope]>
>(scope: Scope, event: Event) {
    // It errors here with:
    // Argument of type '`${Scope}:${Event}`' is not assignable to parameter of type '`${Scope}:${Keyof<Registry[`${Scope}`]>}`'.(2345)
    f1(`${scope}:${event}`)
}

🙁 Actual behavior

When calling the function f1 with a template literal value built with the same types than the template literal type parameter, it errors with:

Argument of type '${Scope}:${Event}' is not assignable to parameter of type '${Scope}:${Keyof<Registry[${Scope}]>}'.(2345)

🙂 Expected behavior

When calling the function f1 with a template literal value built with the same types than the template literal type parameter, I would expect no error.

Additional information about the issue

The message error message has changed over time, in versions 4.1.5 and 4.2.3 it was:

Argument of type 'string' is not assignable to parameter of type 'never'. (2345)

Since version 4.3.5 it is:

Argument of type '${Scope}:${Event}' is not assignable to parameter of type '${Scope}:${Keyof<Registry[${Scope}]>}'.(2345)

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Dec 8, 2023
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 8, 2023
@RyanCavanaugh
Copy link
Member

Seems like a problem in inference rather than assignability. The call works with explicit type args:

function f2<
    Scope extends Keyof<Registry>,
    Event extends Keyof<Registry[Scope]>
>(scope: Scope, event: Event) {
    // OK
    f1<Scope, Event>(`${scope}:${event}`);
}

@patrick-bricout-spendesk
Copy link
Author

Thanks for response Ryan, this is good to know that I can use this workaround which is not too cumbersome for now.

@gabritto
Copy link
Member

An example that doesn't involve string types (and is therefore not fixed by #55371) of the same inference problem:

interface NMap {
  1: 'A'
  2: 'B'
}

declare const g: <T extends 1 | 2>(x: `${T}`) => NMap[T]

type G1 = <T extends 1 | 2>(x: `${T}`) => NMap[T]
const g1: G1 = g; // error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants