-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: better literal differentiation (#107)
* fix: better literal differentiation * updates * simplify * unused imports * readme * number test
- Loading branch information
Showing
47 changed files
with
438 additions
and
245 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import type { | ||
IsNumberLiteral, | ||
IsBooleanLiteral, | ||
Any, | ||
All, | ||
IsStringLiteral, | ||
IsStringLiteralArray, | ||
} from './literals.js' | ||
|
||
namespace LiteralsTests { | ||
// IsNumberLiteral | ||
type testINL1 = Expect<Equal<true, IsNumberLiteral<5>>> | ||
type testINL2 = Expect<Equal<false, IsNumberLiteral<number>>> | ||
|
||
// IsBooleanLiteral | ||
type testIBL1 = Expect<Equal<IsBooleanLiteral<true>, true>> | ||
type testIBL2 = Expect<Equal<IsBooleanLiteral<false>, true>> | ||
type testIBL3 = Expect<Equal<IsBooleanLiteral<boolean>, false>> | ||
|
||
// Any | ||
type testAny1 = Expect<Equal<Any<[true, false]>, true>> | ||
type testAny2 = Expect<Equal<Any<[true, boolean]>, true>> | ||
type testAny3 = Expect<Equal<Any<[false, boolean]>, false>> | ||
type testAny4 = Expect<Equal<Any<[false, false]>, false>> | ||
type testAny5 = Expect<Equal<Any<[]>, false>> | ||
type testAny6 = Expect<Equal<Any<boolean[]>, false>> | ||
|
||
// All | ||
type testAll1 = Expect<Equal<All<[true, true]>, true>> | ||
type testAll2 = Expect<Equal<All<[true, false]>, false>> | ||
type testAll3 = Expect<Equal<All<[true, boolean]>, false>> | ||
type testAll4 = Expect<Equal<All<[false, boolean]>, false>> | ||
type testAll5 = Expect<Equal<All<[false, false]>, false>> | ||
type testAll6 = Expect<Equal<All<[]>, true>> | ||
type testAll7 = Expect<Equal<All<boolean[]>, false>> | ||
|
||
// IsStringLiteral | ||
type testISL1 = Expect<Equal<true, IsStringLiteral<'foo'>>> | ||
type testISL2 = Expect<Equal<true, IsStringLiteral<Uppercase<'foo'>>>> | ||
type testISL3 = Expect< | ||
Equal<false, IsStringLiteral<Uppercase<`foo${string}`>>> | ||
> | ||
type testISL4 = Expect<Equal<false, IsStringLiteral<`foo${string}`>>> | ||
type testISL5 = Expect<Equal<false, IsStringLiteral<`foo${number}`>>> | ||
type testISL6 = Expect<Equal<false, IsStringLiteral<string>>> | ||
type testISL7 = Expect<Equal<false, IsStringLiteral<Lowercase<string>>>> | ||
type testISL8 = Expect< | ||
Equal<false, IsStringLiteral<Uppercase<Lowercase<string>>>> | ||
> | ||
type testISL9 = Expect<Equal<true, IsStringLiteral<'abc' | 'def'>>> | ||
type testISL10 = Expect<Equal<true, IsStringLiteral<Capitalize<'abc'>>>> | ||
type testISL11 = Expect<Equal<true, IsStringLiteral<Uncapitalize<'abc'>>>> | ||
type testISL12 = Expect<Equal<false, IsStringLiteral<`${string}abc`>>> | ||
type testISL13 = Expect< | ||
Equal<false, IsStringLiteral<'abc' | Uppercase<string>>> | ||
> | ||
type testISL14 = Expect<Equal<true, IsStringLiteral<`${boolean}bar`>>> | ||
type testISL15 = Expect<Equal<true, IsStringLiteral<`${undefined}bar`>>> | ||
type testISL16 = Expect<Equal<true, IsStringLiteral<`${null}bar`>>> | ||
type testISL17 = Expect<Equal<false, IsStringLiteral<`${number}`>>> | ||
|
||
// IsStringLiteralArray | ||
type testISLA1 = Expect<Equal<IsStringLiteralArray<['foo', 'bar']>, true>> | ||
type testISLA2 = Expect<Equal<IsStringLiteralArray<string[]>, false>> | ||
type testISLA3 = Expect< | ||
Equal<IsStringLiteralArray<['abc', 'def', string]>, false> | ||
> | ||
} | ||
|
||
test('dummy test', () => expect(true).toBe(true)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* Returns true if input number type is a literal | ||
*/ | ||
type IsNumberLiteral<T extends number> = [T] extends [number] | ||
? [number] extends [T] | ||
? false | ||
: true | ||
: false | ||
|
||
type IsBooleanLiteral<T extends boolean> = [T] extends [boolean] | ||
? [boolean] extends [T] | ||
? false | ||
: true | ||
: false | ||
|
||
/** | ||
* Returns true if any elements in boolean array are the literal true (not false or boolean) | ||
*/ | ||
type Any<Arr extends boolean[]> = Arr extends [ | ||
infer Head extends boolean, | ||
...infer Rest extends boolean[], | ||
] | ||
? IsBooleanLiteral<Head> extends true | ||
? Head extends true | ||
? true | ||
: Any<Rest> | ||
: Any<Rest> | ||
: false | ||
|
||
/** | ||
* Returns true if every element in boolean array is the literal true (not false or boolean) | ||
*/ | ||
type All<Arr extends boolean[]> = IsBooleanLiteral<Arr[number]> extends true | ||
? Arr extends [infer Head extends boolean, ...infer Rest extends boolean[]] | ||
? Head extends true | ||
? Any<Rest> | ||
: false // Found `false` in array | ||
: true // Empty array (or all elements have already passed test) | ||
: false // Array/Tuple contains `boolean` type | ||
|
||
/** | ||
* Returns true if string input type is a literal | ||
*/ | ||
type IsStringLiteral<T extends string> = [T] extends [string] | ||
? [string] extends [T] | ||
? false | ||
: Uppercase<T> extends Uppercase<Lowercase<T>> | ||
? Lowercase<T> extends Lowercase<Uppercase<T>> | ||
? true | ||
: false | ||
: false | ||
: false | ||
|
||
type IsStringLiteralArray<Arr extends string[] | readonly string[]> = | ||
IsStringLiteral<Arr[number]> extends true ? true : false | ||
|
||
export type { | ||
IsNumberLiteral, | ||
IsBooleanLiteral, | ||
Any, | ||
All, | ||
IsStringLiteral, | ||
IsStringLiteralArray, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.