You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cannot infer Template Literal Type containing ${number} / ${string} #43060
// ${number} issuetypeA<T>=Textends `${infer U}.${infer V}` ? U|V : nevertypeB=A<`test.1024`>;// This will be "test" | "1024" as expectedtypeC=A<`test.${number}`>;// Expected "test" | `${number}` or "test" | number but this will be nevertypeD<T>=Textends `${infer U}.${number}` ? U : nevertypeE=D<`test.1024`>;// This will be "test" as expectedtypeF=D<`test.${number}`>;// Expected "test" but this will be never// ${string} issuetypeG<T>=Textends `${infer U}.${infer V}` ? U|V : nevertypeH=G<`test.hoge`>;// This will be "test" | "hoge" as expectedtypeI=G<`test.${string}`>;// Expected "test" | `${string}` or "test" | string but this will be nevertypeJ<T>=Textends `${infer U}.${string}` ? U : nevertypeK=J<`test.hoge`>;// This will be "test" as expectedtypeL=J<`test.${string}`>;// Expected "test" but this will be never
🙁 Actual behavior
C type is never.
F type is never.
I type is never.
L type is never.
🙂 Expected behavior
Expected C type to be "test" | `${number}` or "test" | number.
Expected F type to be "test".
Expected I type to be "test" | `${string}` or "test" | string.
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}.
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 as get(`/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 const template seems to be inaccessible.
When doing
constx=4.5;consty=`${x}abc`asconst
y will match against "4.5abc". However, in
constx:number=4.5;consty=`${x}abc`asconst
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?
I'm not sure if these rules would be consistent, but the basic idea would be to not expand const types to strings and allow weak template types to match substitutions directly.
Activity
jcalz commentedon Mar 22, 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}.[-]Cannot infer Template Literal Type containing `${number}`[/-][+]Cannot infer Template Literal Type containing `${number}` / `${string}`[/+]siefkenj commentedon Mar 23, 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
ywill match against"4.5abc". However, inwill 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
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.