-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Add digit
and other character classes to template literal types.
#46674
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
Comments
Theyβre just https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#the-primitives-string-number-and-boolean |
@andrewbranch but the behavior of I am in the apparent minority of people who think that it should correspond to those values This isn't spelled out anywhere that I know of other than GitHub issues. Oh, yeah, see #41893 where I |
@andrewbranch |
Somewhat related: #46109. Basically |
Yeah, I was probably being unhelpfully brief, but I intended to point out that thereβs no such thing as βcharacter classesβ in TypeScript so anything you want to put in a template literal type hole must be a first-class type, so I think this suggestion might be a bigger can of worms than you may have realized (and/or actually be a duplicate of issues that have nothing to do with template literal types, things asking for |
Admittedly, it does seem a bit odd that TS wants to see first-class types in a position where it's actually going to match it against a specific string representation of said type. Template literal types don't really have much to do with actual template literals at the end of the day, they are effectively just a poor man's regex engine piggybacking on the type system. |
@fatcerberus but it looks like only Every other type you are allowed to put inside a template literal type hole seems to obey a straightforward rule like " Like, if But with |
I know this is an old issue, but just wanted to give another example/reason why I think it makes sense to implement this, and perhaps another way to implement a solution. Lots of time people end up implementing a Digit type like:
Then do things like However, none of that combinatorial explosion applies to So, perhaps reframing the issue as: Could it be possible to define a "character class" type that is only designed to be used in template literal type placeholders such that, instead of blowing out the combination of all possible union types, that "character class type" could be thought of as defining a function for acceptable input strings, just like the way I'm not very familiar with the innards of TypeScript so apologies if this approach has obvious shortcomings, just seems like a way to get the benefits of the way |
For people looking for string-like int type, let intStr: `${bigint}`
intStr = `23` // allowed
intStr = `0b101` // allowed
intStr = `1.23` // error |
This is really cool but it still allows octal/hex formats through :( EDIT: This works better. export type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
export type StringNumber<T extends string, V = T> = T extends Digit
? V
: T extends `${Digit}${infer R}`
? StringNumber<R, V>
: `0` |
Suggestion
π Search Terms
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
Typescript's template literal types support some built-in non-string types including number. These types are not documented anywhere I can find, certainly not the Template Literal Types page.
${number}
matches any string thatNumber
can parse, which includes floating points, hex, binary and scientific notation.I think typescript users will use
${number}
to incorrectly define types that should only accept decimals. I recommend addingDigits
and other common character classes1π Motivating Example
Using
${number}px
seems like an interesting way to define api's that require css pixel values like10px
but TypeScript's definition of${number}
allows unexpected values like0x1px
which aren't supported by css. I can find that exact example in the typescript codebaseI don't expect TypeScript to understand CSS syntax, but the behavior of
${number}
leads to allowing values that are not valid css units. I think${number}
is generally not the behavior that people expect and it will be miss used (especially because it's not well documented).π» Use Cases
Refining the current
${number}
usecase.Footnotes
Maybe using POSIX character classes as a starting point β©
The text was updated successfully, but these errors were encountered: