Add `trim` as new intrinsic for use with template literal types
See original GitHub issueSearch Terms
intrinsic trim whitespace
possible related: https://github.com/microsoft/TypeScript/issues/41210
Suggestion
Add trim
as a new intrinsic alongside the existing intrinsic types:
Uppercase
Lowercase
Capitalize
Uncapitalize
Use Cases
Trim can be implemented with the current types pretty easily by doing something like:
type Whitespace = '\n' | ' ';
type Trim<T> = T extends `${Whitespace}${infer U}` ? Trim<U> : T extends `${infer U}${Whitespace}` ? Trim<U> : T;
But this can quickly run into depth limits if there is a lot of repeated whitespace.
type Whitespace = | '\n'| ' ' | 'x' // Add x as whitespace to make example easier to read
type Trim<T> = T extends `${Whitespace}${infer U}` ? Trim<U> : T extends `${infer U}${Whitespace}` ? Trim<U> : T;
type Test = Trim<`abc
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
`>
This can be improved by adding strings of repeated whitespace to the Whitespace type, but will still run into limitations:
type Whitespace = | '\n' | ' ' | ' ' | ' ' | ' ' | ' ' | ' '
type Trim<T> = T extends `${Whitespace}${infer U}` ? Trim<U> : T extends `${infer U}${Whitespace}` ? Trim<U> : T;
This seems like a good case for an intrinsic implementation since it is a fairly simple and common operation on strings.
One use case would be to correctly type template literal helpers that trim leading indent whitespace, but there are probably many cases where trimming whitespace from a string would be useful.
Examples
Trim<`
abc
`> // 'abc'
Checklist
My suggestion meets these guidelines:
- This wouldn’t be a breaking change in existing TypeScript/JavaScript code
- This wouldn’t change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript’s Design Goals.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:13
- Comments:6 (3 by maintainers)
As I said above, that example is a bit contrived.
dedent
would be a utility function that can be used in combitation with template strings anywhere in the code base, and I have mostly used similar functions to format text from template string before showing them to a user eg:which would print something like:
Since
dedent
is generic, the string would “make it into the type system” through inference. It wouldn’t be particularly useful by itself though, and the only benefit in this case would be to give you a better tool tip when hovering over helpText. I am not arguing this is a good use case or example, and I see that this isn’t really a helpful use case by itself, its just the other place where I had used Trim when I was playing around with potential use cases for new features in 4.1.I could imagine a use case for having additional formatting functions, that may expect a multi-line string or string with other constraints that could be combined with this to produce a combination of constraints that do actually limit the valid strings you can use, but again I’m not sure how valuable that actually is as a real world use case.
I think its fair to table this, or close it until there are use cases with more real world value.
How would strings like that make it into the type system in the first place, though?