Skip to content

Template literal value not assignable to template literal type #56659

Closed

Description

🔎 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)

Activity

  1. RyanCavanaugh commented on Dec 8, 2023

    @RyanCavanaugh
    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}`);
    }
  2. patrick-bricout-spendesk commented on Dec 11, 2023

    @patrick-bricout-spendesk
    Author

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

  3. gabritto commented on Jan 25, 2024

    @gabritto
    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
  4. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions