Repository navigation
Cannot infer Template Literal Type containing ${number} / ${string} #43060
Description
Activity
- addedNeeds InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
on Mar 9, 2021 I'm sure this goes without saying, but the issue here is not specific to
${number}, but occurs for all "pattern" template literals (as implemented in #40598) like${string}.Reacted by Kotaro Sugawara and Jason Siefken- changed the title
[-]Cannot infer Template Literal Type containing `${number}`[/-][+]Cannot infer Template Literal Type containing `${number}` / `${string}`[/+]on Mar 22, 2021 I just came across this issue when trying to type a REST API. I made a type using templates that could successfully determine the appropriate return type of
get("/sessions/43/posts"), however, my API is most commonly called asget(`/sessions/${sessionId}/posts` as const), which TypeScript failed to recognize.For my purposes, I would be happy if there were some way to tell TypeScript to interpret a template string as a string literal. E.g.,
`abc${x}` === "abc${x}".Some confusion I have with the current implementation is that type type of a
consttemplate seems to be inaccessible.When doing
const x = 4.5; const y = `${x}abc` as const
ywill match against"4.5abc". However, inconst x:number = 4.5; const y = `${x}abc` as const
will not match against anything more specific than
string(correct me if I'm wrong...), and yet TypeScript will show the type as`${number}abc`.Perhaps tagged-template syntax could be used to specify a template as abstract or weakly inferred?
For example
type A<T> = T extends `${infer U}.${infer V}` ? U | V : never type B<T> = T extends weak`${infer U}.${infer V}` ? U | V : never const x = 4.5 const y:number = 4.5 type X = A<`${typeof x}.abc`> // "4" | "5.abc" type Y = A<`${typeof y}.abc`> // never type WeakX = B<`${typeof x}.abc`> // 4.5 | "abc" OR `${4.5}` | "abc" type WeakY = B<`${typeof y}.abc`> // number | "abc" OR `${number}` | "abc" type WeakXMovedDecimal = B<`${typeof x}a.bc`> // "4.5a" | "bc" OR `${4.5}a` | "bc" type WeakYMovedDecimal = B<`${typeof y}a.bc`> // string | "bc" OR `${number}a` | "bc" const z1:`${typeof x}abc` = `${x}abc` // Okay const z2:`${typeof y}abc` = `${y}abc` // Fails typechecking const z3:weak`${typeof x}abc` = `${x}abc` // Okay const z4:weak`${typeof y}abc` = `${y}abc` // Okay
I'm not sure if these rules would be consistent, but the basic idea would be to not expand
consttypes to strings and allowweaktemplate types to match substitutions directly.Reacted by Kotaro Sugawara- addedFixedA PR has been merged for this issueA PR has been merged for this issueSuggestionAn idea for TypeScriptAn idea for TypeScriptand removedNeeds InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
on May 1, 2021
Bug Report
Cannot infer Template Literal Type containing
${number}/${string}🔎 Search Terms
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Ctype isnever.Ftype isnever.Itype isnever.Ltype isnever.🙂 Expected behavior
Ctype to be"test" | `${number}`or"test" | number.Ftype to be"test".Itype to be"test" | `${string}`or"test" | string.Ltype to be"test".