Skip to content

Commit

Permalink
Fix issue with IsNumeric when input is whitespace (#539)
Browse files Browse the repository at this point in the history
  • Loading branch information
bconnorwhite authored Jan 13, 2023
1 parent d02e11a commit a82342a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 3 deletions.
46 changes: 45 additions & 1 deletion source/internal.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {Primitive} from './primitive';
import type {Simplify} from './simplify';
import type {Trim} from './trim';

/**
Infer the length of the given array `<T>`.
Expand Down Expand Up @@ -47,6 +48,34 @@ export type WordSeparators = '-' | '_' | ' ';

export type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';

export 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}';

/**
Matches any unknown record.
*/
Expand Down Expand Up @@ -109,10 +138,25 @@ Returns a boolean for whether the string is uppercased.
*/
export type IsUpperCase<T extends string> = T extends Uppercase<T> ? true : false;

/**
Returns a boolean for whether a string is whitespace.
*/
export type IsWhitespace<T extends string> = T extends Whitespace
? true
: T extends `${Whitespace}${infer Rest}`
? IsWhitespace<Rest>
: false;

/**
Returns a boolean for whether the string is numeric.
This type is a workaround for [Microsoft/TypeScript#46109](https://github.com/microsoft/TypeScript/issues/46109#issuecomment-930307987).
*/
export type IsNumeric<T extends string> = T extends `${number}` ? true : false;
export type IsNumeric<T extends string> = T extends `${number}`
? Trim<T> extends T
? true
: false
: false;

/**
Returns a boolean for whether the the type is `any`.
Expand Down
6 changes: 4 additions & 2 deletions source/trim.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type {Whitespace} from './internal';

/**
Remove spaces from the left side.
*/
type TrimLeft<V extends string> = V extends ` ${infer R}` ? TrimLeft<R> : V;
type TrimLeft<V extends string> = V extends `${Whitespace}${infer R}` ? TrimLeft<R> : V;

/**
Remove spaces from the right side.
*/
type TrimRight<V extends string> = V extends `${infer R} ` ? TrimRight<R> : V;
type TrimRight<V extends string> = V extends `${infer R}${Whitespace}` ? TrimRight<R> : V;

/**
Remove leading and trailing spaces from a string.
Expand Down
29 changes: 29 additions & 0 deletions test-d/internal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {expectType} from 'tsd';
import type {IsWhitespace, IsNumeric} from '../source/internal';

expectType<IsWhitespace<''>>(false);
expectType<IsWhitespace<' '>>(true);
expectType<IsWhitespace<'\n'>>(true);
expectType<IsWhitespace<'\u{9}'>>(true);
expectType<IsWhitespace<'a'>>(false);
expectType<IsWhitespace<'a '>>(false);
expectType<IsWhitespace<' '>>(true);
expectType<IsWhitespace<' \t '>>(true);

expectType<IsNumeric<''>>(false);
expectType<IsNumeric<'0'>>(true);
expectType<IsNumeric<'1'>>(true);
expectType<IsNumeric<'-1'>>(true);
expectType<IsNumeric<'123'>>(true);
expectType<IsNumeric<'1e2'>>(true);
expectType<IsNumeric<'1.23'>>(true);
expectType<IsNumeric<'123.456'>>(true);
expectType<IsNumeric<'1.23e4'>>(true);
expectType<IsNumeric<'1.23e-4'>>(true);
expectType<IsNumeric<' '>>(false);
expectType<IsNumeric<'\n'>>(false);
expectType<IsNumeric<'\u{9}'>>(false);
expectType<IsNumeric<' 1.2'>>(false);
expectType<IsNumeric<'1 2'>>(false);
expectType<IsNumeric<'1_200'>>(false);
expectType<IsNumeric<' 1 '>>(false);
2 changes: 2 additions & 0 deletions test-d/trim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ expectType<'bar'>(trim('bar '));
expectType<'baz'>(trim(' baz '));
expectType<'waldo'>(trim(' waldo '));
expectType<'fr ed'>(trim(' fr ed '));
expectType<'foo'>(trim(' foo\n'));
expectType<'foo'>(trim(' foo\n\t '));

0 comments on commit a82342a

Please sign in to comment.