Skip to content

Number in Template Literal fails type assertion to String Literal Type (4.5 Breaking Change) #46901

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

Closed
NoelAbrahams opened this issue Nov 22, 2021 · 2 comments

Comments

@NoelAbrahams
Copy link

Bug Report

πŸ”Ž Search Terms

4.5 literal

πŸ•— Version & Regression Information

This changed between versions 4.4 and 4.5

⏯ Playground Link

https://www.typescriptlang.org/play?ts=4.5.2#code/LAKALgngDgpgBAMQPZLgXjgcgN4EsAmAvgPQBGAhgE6YDcooAZgK4B2AxmLki3AygBQsmAWwBccIcNIxKASjjjkqbKDhq4q9ZRhgmlHgAMAJNkkkKlA3HIBnLHiJkqtTWuLFtu-XGOmR5qitbOBswSlwWAHNrOxwCAOo6EEIgA

πŸ’» Code

type Foo = '{id}/bar';

function foo(num: number) : Foo {
    
    return `${num}/bar` as '{id}/bar'

  // Workaround
 //  return `${num}/bar` as string as '{id}/bar'
}

// Also okay
function foo(num: string /*change to string*/) : Foo {
    return `${num}/bar` as '{id}/bar';
}

πŸ™ Actual behaviour

Error:

Conversion of type '${number}/bar' to type '"{id}/bar"' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

πŸ™‚ Expected behaviour

No Error

Remarks

  • This is quite a large breaking change that we are experiencing.
  • It's not mentioned in the 'breaking changes' of the release notes.
  • It's not clear why this should be an error.
  • The workaround of having a type assertion for string seems pretty useless as toString on a number is always a faithful representation of the number (that's the reasoning by which TypeScript allows for number to be used in Index Signatures).
  • Also briefly reported by Google here: Google feedback on TS 4.5-betaΒ #46665
@NoelAbrahams NoelAbrahams changed the title Number in Template Literal fails type assertion to Template Literal Type (4.5 Breaking Change) Number in Template Literal fails type assertion to String Literal Type (4.5 Breaking Change) Nov 22, 2021
@RyanCavanaugh
Copy link
Member

It's not clear why this should be an error.

There is no numeric value you can pass to the first foo that will cause it to return the value "{id}/bar".

This isn't the case in the second example; calling foo("{id}") will cause it to return that value.

Erroring on a type assertion that is known with certainty to be unsound seems like the expected behavior.

It almost seems like you were intending to write

type id = number;
type Foo = `${id}/bar`;

function foo1(num: number) : Foo {
    // OK
    return `${num}/bar`;
}

but didn't?

@NoelAbrahams
Copy link
Author

There is no numeric value you can pass to the first foo that will cause it to return the value "{id}/bar".

Indeed. It's brilliant to see TypeScript picking out hacks that we have put in place in the past.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants