Suggestion
📃 Motivating Example
Strings, in particular key names, sometimes affect types based on the format of the string, most commonly with prefixes. One such example is the recent W3C Design Tokens spec which uses a $ prefix to reserve key names like $description and $type.
Right now it's possible to create a positive match such as:
type CssCustomPropertyName = `--${string}`
But there's no way to create a negative match. Or in regex terms:
The goal here wouldn't be to recreate all the functionality of regex/parsing, it would be to handle the stringy-typing sometimes seen in JavaScript (including within official web specifications).
⭐ Suggestion
Note: This is one option, I'm not particularly tied to it and could suggest alternatives if this is not workable.
Expose, in a limited capacity, the not operator (#29317) so that it can be used to filter strings.
type Name = string & not `--${string}`
let a: Name = "--x" // err!
let b: Name = "--" // err!
let c: Name = "x" // ok
let d: Name = "x--" // ok
let e: Name = "-x" // ok
There is an existing PR adding a not operator, but has been long stalled on expected behavior. But maybe just this one piece could be added and slowly expanded from, if desired, later.
💻 Use Cases
The W3C Design Tokens spec does not allow token/group names starting with a $ or containing any of the characters .{}.
Using negated string matches, you could correctly type this:
type Name = string & not `$${string}`
interface Group {
$description?: string;
$type?: string;
[key: Name]: Token | Group
}
The closest you can get to this today is:
type LowerAlpha = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
type UpperAlpha = Uppercase<LowerAlpha>
type Numeric = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
type AlphaNumeric = LowerAlpha | UpperAlpha | Numeric
type SafeSymbols = "-" | "_" | " "
type NameStart = AlphaNumeric | SafeSymbols
type Name = `${NameStart}${string}`
type Group = {
$description?: string;
$type?: string;
} & {
[key in Name]: Group
}
let group: Group = {
$description: "",
$type: "",
"my cool name": {}
}
🔍 Search Terms
List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.
- String
- Negated
- Pattern
- Regex
- Regular Expression
- Not
- Prefix
- Suffix
✅ Viability Checklist
My suggestion meets these guidelines:
Suggestion
📃 Motivating Example
Strings, in particular key names, sometimes affect types based on the format of the string, most commonly with prefixes. One such example is the recent W3C Design Tokens spec which uses a
$prefix to reserve key names like$descriptionand$type.Right now it's possible to create a positive match such as:
But there's no way to create a negative match. Or in regex terms:
The goal here wouldn't be to recreate all the functionality of regex/parsing, it would be to handle the stringy-typing sometimes seen in JavaScript (including within official web specifications).
⭐ Suggestion
Expose, in a limited capacity, the
notoperator (#29317) so that it can be used to filter strings.There is an existing PR adding a
notoperator, but has been long stalled on expected behavior. But maybe just this one piece could be added and slowly expanded from, if desired, later.💻 Use Cases
The W3C Design Tokens spec does not allow token/group names starting with a
$or containing any of the characters.{}.Using negated string matches, you could correctly type this:
The closest you can get to this today is:
🔍 Search Terms
List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.
✅ Viability Checklist
My suggestion meets these guidelines: