Skip to content

Commit

Permalink
feat: literal string type-level trimming
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-mitchell committed Mar 20, 2023
1 parent 40cd948 commit 92ee3f4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
42 changes: 39 additions & 3 deletions index.d.ts
@@ -1,3 +1,39 @@
// Source: https://github.com/sindresorhus/type-fest/blob/main/source/internal.d.ts#L49
type Whitespace =
| '\u{9}' // '\t'
| '\u{A}' // '\n'
| '\u{B}' // '\v'
| '\u{C}' // '\f'
| '\u{D}' // '\r'
| '\u{20}' // ' '
| '\u{85}'
| '\u{A0}'
| '\u{1680}'
| '\u{2000}'
| '\u{2001}'
| '\u{2002}'
| '\u{2003}'
| '\u{2004}'
| '\u{2005}'
| '\u{2006}'
| '\u{2007}'
| '\u{2008}'
| '\u{2009}'
| '\u{200A}'
| '\u{2028}'
| '\u{2029}'
| '\u{202F}'
| '\u{205F}'
| '\u{3000}'
| '\u{FEFF}';

// Source: https://github.com/sindresorhus/type-fest/blob/main/source/trim.d.ts
type TrimStart<S extends string> = S extends `${Whitespace}${infer R}` ? TrimStart<R> : S;

type TrimEnd<S extends string> = S extends `${infer R}${Whitespace}` ? TrimEnd<R> : S;

export type Trim<S extends string> = TrimStart<TrimEnd<S>>;

/**
Trim from the start and end of a string.
Expand All @@ -9,7 +45,7 @@ trimNewlines('\n🦄\r\n');
//=> '🦄'
```
*/
export function trimNewlines(string: string): string;
export function trimNewlines<S extends string>(string: S): Trim<S>;

/**
Trim from the start of a string.
Expand All @@ -22,7 +58,7 @@ trimNewlines.start('\n🦄\r\n');
//=> '🦄\r\n'
```
*/
export function trimNewlinesStart(string: string): string;
export function trimNewlinesStart<S extends string>(string: S): TrimStart<S>;

/**
Trim from the end of a string.
Expand All @@ -35,4 +71,4 @@ trimNewlines.end('\n🦄\r\n');
//=> '\n🦄'
```
*/
export function trimNewlinesEnd(string: string): string;
export function trimNewlinesEnd<S extends string>(string: S): TrimEnd<S>;
18 changes: 14 additions & 4 deletions index.test-d.ts
@@ -1,6 +1,16 @@
import {expectType} from 'tsd';
import {expectType, expectAssignable} from 'tsd';
import {trimNewlines, trimNewlinesStart, trimNewlinesEnd} from './index.js';

expectType<string>(trimNewlines('\n🦄\r\n'));
expectType<string>(trimNewlinesStart('\n\n🦄\n'));
expectType<string>(trimNewlinesEnd('\n🦄\n\n'));
expectAssignable<string>(trimNewlines('\n🦄\r\n'));
expectAssignable<string>(trimNewlinesStart('\n\n🦄\n'));
expectAssignable<string>(trimNewlinesEnd('\n🦄\n\n'));

expectType<'🦄'>(trimNewlines('\n🦄\r\n'));
expectType<'🦄\n'>(trimNewlinesStart('\n\n🦄\n'));
expectType<'\n🦄'>(trimNewlinesEnd('\n🦄\n\n'));

declare const _string: string;

expectType<string>(trimNewlines(_string));
expectType<string>(trimNewlinesStart(_string));
expectType<string>(trimNewlinesEnd(_string));

0 comments on commit 92ee3f4

Please sign in to comment.