inferred-types 0.33.4 → 0.34.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -0
- package/dist/index.d.ts +204 -103
- package/dist/index.js +20 -6
- package/dist/index.mjs +17 -6
- package/package.json +3 -3
- package/src/runtime/combinators/or.ts +4 -14
- package/src/runtime/type-checks/isArray.ts +30 -1
- package/src/runtime/type-checks/isBoolean.ts +1 -1
- package/src/runtime/type-checks/isFalse.ts +24 -12
- package/src/runtime/type-checks/isObject.ts +1 -1
- package/src/runtime/type-checks/isString.ts +1 -1
- package/src/runtime/type-checks/isTrue.ts +13 -29
- package/src/runtime/type-checks/isUndefined.ts +1 -1
- package/src/runtime/type-checks/startsWith.ts +9 -11
- package/src/types/Mutable.ts +1 -1
- package/src/types/Narrowable.ts +1 -2
- package/src/types/boolean-logic/EndsWith.ts +40 -0
- package/src/types/boolean-logic/Extends.ts +22 -0
- package/src/types/{type-checks → boolean-logic}/Includes.ts +3 -4
- package/src/types/{type-checks → boolean-logic}/IsLiteral.ts +52 -5
- package/src/types/boolean-logic/IsScalar.ts +20 -0
- package/src/types/{type-checks → boolean-logic}/IsUndefined.ts +5 -1
- package/src/types/boolean-logic/Or.ts +12 -0
- package/src/types/{type-checks → boolean-logic}/StartsWith.ts +12 -13
- package/src/types/{type-checks → boolean-logic}/TypeDefault.ts +1 -1
- package/src/types/boolean-logic/array.ts +57 -0
- package/src/types/boolean-logic/boolean.ts +84 -0
- package/src/types/boolean-logic/equivalency.ts +15 -0
- package/src/types/{type-checks → boolean-logic}/index.ts +4 -3
- package/src/types/{type-checks → boolean-logic}/object.ts +4 -1
- package/src/types/{type-checks → boolean-logic}/string.ts +1 -1
- package/src/types/dictionary/MapTo.ts +1 -1
- package/src/types/functions/LogicFunction.ts +1 -1
- package/src/types/index.ts +1 -1
- package/src/types/lists/FilterTuple.ts +20 -0
- package/src/types/lists/index.ts +1 -0
- package/tests/boolean-logic/Contains.test.ts +55 -0
- package/tests/{TypeInfo → boolean-logic}/IsLiteral.spec.ts +0 -0
- package/tests/dictionary/{PrependValuesWithFunction.ts → PrependValuesWithFunction.test.ts} +0 -0
- package/tests/dictionary/TypeDefault.test.ts +1 -1
- package/tests/lists/Length.test.ts +19 -0
- package/tests/runtime/if-is.spec.ts +113 -5
- package/src/types/type-checks/EndsWith.ts +0 -22
- package/src/types/type-checks/Extends.ts +0 -14
- package/src/types/type-checks/IsBooleanLiteral.ts +0 -16
- package/src/types/type-checks/IsNumericLiteral.ts +0 -16
- package/src/types/type-checks/IsScalar.ts +0 -14
- package/src/types/type-checks/IsStringLiteral.ts +0 -14
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Or } from "src/types/boolean-logic/Or";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* **Note:** a "logic function" is any function which returns a boolean
|
|
8
|
-
*/
|
|
9
|
-
export const or = <T extends any[]>(...ops: LogicFunction<T>[]): LogicFunction<T> => {
|
|
10
|
-
const fn: LogicFunction<T> = (...args: T) => {
|
|
11
|
-
return [...ops].some((i) => i(...args));
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
return fn;
|
|
15
|
-
};
|
|
3
|
+
export function or<O extends readonly boolean[]>(...conditions: O) {
|
|
4
|
+
return (conditions.some((v) => v === true) ? true : false) as Or<O>;
|
|
5
|
+
}
|
|
@@ -1,5 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
import { IsArray, IfArray } from "src/types/boolean-logic/array";
|
|
2
|
+
import { Narrowable } from "src/types/Narrowable";
|
|
2
3
|
|
|
3
4
|
export function isArray<T>(i: T) {
|
|
4
5
|
return (Array.isArray(i) === true) as IsArray<T>;
|
|
5
6
|
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* **ifArray**(T, IF, ELSE)
|
|
10
|
+
*
|
|
11
|
+
* A utility which evaluates a type `T` for whether it is an array and then
|
|
12
|
+
*/
|
|
13
|
+
export function ifArray<
|
|
14
|
+
// value which is possibly an array
|
|
15
|
+
T extends Narrowable,
|
|
16
|
+
// functions which return a known type
|
|
17
|
+
IF extends Narrowable,
|
|
18
|
+
ELSE extends Narrowable
|
|
19
|
+
>(
|
|
20
|
+
val: T,
|
|
21
|
+
isAnArray: <N extends T & readonly any[]>(arr: N) => IF,
|
|
22
|
+
isNotAnArray: <N extends Exclude<T, any[]>>(nonArr: N) => ELSE
|
|
23
|
+
) {
|
|
24
|
+
return (isArray(val) ? isAnArray(val as any) : isNotAnArray(val as any)) as IfArray<T, IF, ELSE>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function ifArrayPartial<T extends Narrowable>() {
|
|
28
|
+
return <IF extends Narrowable, ELSE extends Narrowable>(
|
|
29
|
+
isAnArray: <N extends T & readonly any[]>(arr: N) => IF,
|
|
30
|
+
isNotAnArray: <N extends Exclude<T, any[]>>(nonArr: N) => ELSE
|
|
31
|
+
) => {
|
|
32
|
+
return <V extends T>(val: V) => ifArray(val, isAnArray, isNotAnArray);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -1,17 +1,29 @@
|
|
|
1
|
+
import { IfFalse, IsFalse } from "src/types/boolean-logic/boolean";
|
|
1
2
|
import { Narrowable } from "src/types/Narrowable";
|
|
2
|
-
import { IsBoolean } from "./isBoolean";
|
|
3
|
-
|
|
4
|
-
export type IsFalse<T extends Narrowable> = IsBoolean<T> extends true
|
|
5
|
-
? // is a boolean
|
|
6
|
-
T extends false
|
|
7
|
-
? true
|
|
8
|
-
: true extends T
|
|
9
|
-
? false
|
|
10
|
-
: // is of boolean type; therefore narrow type is unknown
|
|
11
|
-
unknown
|
|
12
|
-
: // not a boolean
|
|
13
|
-
false;
|
|
14
3
|
|
|
15
4
|
export function isFalse<T>(i: T) {
|
|
16
5
|
return (typeof i === "boolean" && !i) as IsFalse<T>;
|
|
17
6
|
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* **ifTrue**
|
|
10
|
+
*
|
|
11
|
+
* Strongly type-aware conditional statement which checks whether a value is
|
|
12
|
+
* a _true_ and returns one of two values (strongly typed) based on the evaluation
|
|
13
|
+
* of this criteria.
|
|
14
|
+
*
|
|
15
|
+
* @param val the value being tested
|
|
16
|
+
* @param ifVal the value (strongly typed) returned if val is _true_ value
|
|
17
|
+
* @param elseVal the value (strongly typed) returned if val is NOT a _true_ value
|
|
18
|
+
*
|
|
19
|
+
* Note: at runtime there's no way to distinguish if the value was widely or loosely
|
|
20
|
+
* typed so unlike the type utility there is no "MAYBE" state but if a wide type if
|
|
21
|
+
* encountered the _type_ will the union of `IF` and `ELSE`.
|
|
22
|
+
*/
|
|
23
|
+
export function ifFalse<T extends boolean, IF extends Narrowable, ELSE extends Narrowable>(
|
|
24
|
+
val: T,
|
|
25
|
+
ifVal: IF,
|
|
26
|
+
elseVal: ELSE
|
|
27
|
+
) {
|
|
28
|
+
return (isFalse(val) ? ifVal : elseVal) as IfFalse<T, IF, ELSE, IF | ELSE>;
|
|
29
|
+
}
|
|
@@ -1,28 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Type utility which returns `true` or `false` based on
|
|
6
|
-
* whether the type holds the narrow "true" type.
|
|
7
|
-
* ```ts
|
|
8
|
-
* // true
|
|
9
|
-
* type T = IsTrue<true>;
|
|
10
|
-
* // unknown
|
|
11
|
-
* type U = IsTrue<boolean>;
|
|
12
|
-
* // false
|
|
13
|
-
* type F = IsTrue<false>;
|
|
14
|
-
* type F2 = IsTrue<"false">;
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export type IsTrue<T> = IsBoolean<T> extends true
|
|
18
|
-
? // is a boolean
|
|
19
|
-
T extends true
|
|
20
|
-
? true
|
|
21
|
-
: T extends false
|
|
22
|
-
? false
|
|
23
|
-
: unknown
|
|
24
|
-
: // not a boolean
|
|
25
|
-
false;
|
|
1
|
+
import { IfTrue, IsTrue } from "src/types/boolean-logic";
|
|
2
|
+
import { Narrowable } from "src/types/Narrowable";
|
|
26
3
|
|
|
27
4
|
/**
|
|
28
5
|
* Run-time and type checking of whether a variable is `true`.
|
|
@@ -35,13 +12,20 @@ export function isTrue<T extends Narrowable>(i: T) {
|
|
|
35
12
|
* **ifTrue**
|
|
36
13
|
*
|
|
37
14
|
* Strongly type-aware conditional statement which checks whether a value is
|
|
38
|
-
*
|
|
39
|
-
* of this criteria.
|
|
15
|
+
* _true_.
|
|
40
16
|
*
|
|
41
17
|
* @param val the value being tested
|
|
42
18
|
* @param ifVal the value (strongly typed) returned if val is _true_ value
|
|
43
19
|
* @param elseVal the value (strongly typed) returned if val is NOT a _true_ value
|
|
20
|
+
*
|
|
21
|
+
* Note: at runtime there's no way to distinguish if the value was widely or loosely
|
|
22
|
+
* typed so unlike the type utility there is no "MAYBE" state but if a wide type if
|
|
23
|
+
* encountered the _type_ will the union of `IF` and `ELSE`.
|
|
44
24
|
*/
|
|
45
|
-
export function ifTrue<T extends
|
|
46
|
-
|
|
25
|
+
export function ifTrue<T extends boolean, IF extends Narrowable, ELSE extends Narrowable>(
|
|
26
|
+
val: T,
|
|
27
|
+
ifVal: IF,
|
|
28
|
+
elseVal: ELSE
|
|
29
|
+
) {
|
|
30
|
+
return (isTrue(val) ? ifVal : elseVal) as IfTrue<T, IF, ELSE, IF | ELSE>;
|
|
47
31
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Narrowable } from "src/types";
|
|
2
|
-
import { IsUndefined } from "src/types/
|
|
2
|
+
import { IsUndefined } from "src/types/boolean-logic/IsUndefined";
|
|
3
3
|
|
|
4
4
|
export function isUndefined<T extends Narrowable>(i: T) {
|
|
5
5
|
return (typeof i === "undefined") as undefined extends T ? true : false;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Narrowable } from "src/types";
|
|
2
|
+
import { IfStartsWith, StartsWith } from "src/types/boolean-logic";
|
|
3
|
+
import { IfUndefined } from "src/types/boolean-logic/IsUndefined";
|
|
3
4
|
import { createFnWithProps } from "../createFnWithProps";
|
|
4
5
|
import { box, Box } from "../literals";
|
|
5
6
|
import { ifTrue } from "./isTrue";
|
|
@@ -88,22 +89,19 @@ export type StringLiteralFn<S extends string = string> = <T extends S>(input: T)
|
|
|
88
89
|
* returns is able to
|
|
89
90
|
*/
|
|
90
91
|
export const ifStartsWith =
|
|
91
|
-
<
|
|
92
|
-
TStartsWith extends string,
|
|
93
|
-
TIf extends <T extends string>(input: T) => any,
|
|
94
|
-
TElse extends <T extends string>(input: T) => any
|
|
95
|
-
>(
|
|
92
|
+
<TStartsWith extends string, TIf extends Narrowable, TElse extends Narrowable>(
|
|
96
93
|
/** the string literal _start value_ which a string must begin with */
|
|
97
94
|
start: TStartsWith,
|
|
98
95
|
/** a mutation function when a value _does_ start with `TStartsWith` */
|
|
99
|
-
isTrue: TIf,
|
|
96
|
+
isTrue: <T extends string>(input: T) => TIf,
|
|
100
97
|
/** an optional mutation function */
|
|
101
|
-
isFalse: TElse
|
|
98
|
+
isFalse: <T extends string>(input: T) => TElse
|
|
102
99
|
) =>
|
|
103
|
-
<
|
|
100
|
+
<TTextValue extends string>(input: TTextValue) =>
|
|
104
101
|
ifTrue(
|
|
105
102
|
// condition
|
|
106
103
|
startsWith(start)(input),
|
|
104
|
+
// handlers
|
|
107
105
|
isTrue(input),
|
|
108
106
|
isFalse(input)
|
|
109
|
-
)
|
|
107
|
+
);
|
package/src/types/Mutable.ts
CHANGED
package/src/types/Narrowable.ts
CHANGED
|
@@ -2,5 +2,4 @@
|
|
|
2
2
|
* A union of types used in conjunction with the `literalValues()` function
|
|
3
3
|
* to produce a _narrow_ type definition of a passed in dictionary object.
|
|
4
4
|
*/
|
|
5
|
-
export type Narrowable =
|
|
6
|
-
string | number | boolean | symbol | object | undefined | void | null | {};
|
|
5
|
+
export type Narrowable = string | number | boolean | symbol | object | undefined | void | null | {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IsStringLiteral } from "src/types/boolean-logic";
|
|
2
|
+
import { Narrowable } from "../Narrowable";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* **EndsWith**<T,U>
|
|
6
|
+
*
|
|
7
|
+
* A type utility which checks whether `T` _ends with_ the string literal `U`.
|
|
8
|
+
*
|
|
9
|
+
* If both `T` and `U` are string literals then the type system will resolve
|
|
10
|
+
* to a literal `true` or `false` but if either is not a literal that it will
|
|
11
|
+
* just resolve to `boolean` as the value can not be known at design time..
|
|
12
|
+
*/
|
|
13
|
+
export type EndsWith<
|
|
14
|
+
TValue extends string,
|
|
15
|
+
TEndsWith extends string
|
|
16
|
+
> = IsStringLiteral<TEndsWith> extends true
|
|
17
|
+
? IsStringLiteral<TValue> extends true // both literals
|
|
18
|
+
? TValue extends `${string}${TEndsWith}`
|
|
19
|
+
? true
|
|
20
|
+
: false
|
|
21
|
+
: boolean
|
|
22
|
+
: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* **IfEndsWith**<TValue, TEndsWith, IF, ELSE, MAYBE>
|
|
26
|
+
*
|
|
27
|
+
* Type utility which converts type to `IF` type _if_ `TValue` _ends with_ `TEndsWith` but
|
|
28
|
+
* otherwise converts type to `ELSE`. If there are wide types in the mix then the type will
|
|
29
|
+
* result in the union of IF and ELSE.
|
|
30
|
+
*/
|
|
31
|
+
export type IfEndsWith<
|
|
32
|
+
TValue extends string,
|
|
33
|
+
TEndsWith extends string,
|
|
34
|
+
IF extends Narrowable,
|
|
35
|
+
ELSE extends Narrowable
|
|
36
|
+
> = EndsWith<TValue, TEndsWith> extends true
|
|
37
|
+
? IF
|
|
38
|
+
: EndsWith<TValue, TEndsWith> extends false
|
|
39
|
+
? ELSE
|
|
40
|
+
: IF | ELSE;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Narrowable } from "../Narrowable";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* **Extends**`<T, EXTENDS>`
|
|
5
|
+
*
|
|
6
|
+
* Boolean type utility which returns `true` if `T` _extends_ `EXTENDS`.
|
|
7
|
+
*/
|
|
8
|
+
export type Extends<T extends Narrowable, EXTENDS extends Narrowable> = T extends EXTENDS
|
|
9
|
+
? true
|
|
10
|
+
: false;
|
|
11
|
+
/**
|
|
12
|
+
* **IfExtends**
|
|
13
|
+
*
|
|
14
|
+
* Branching type utility which returns type `IF` when `E` _extends_ `T`; otherwise
|
|
15
|
+
* it will return the type `ELSE`.
|
|
16
|
+
*/
|
|
17
|
+
export type IfExtends<
|
|
18
|
+
T extends Narrowable,
|
|
19
|
+
EXTENDS extends Narrowable,
|
|
20
|
+
IF extends Narrowable,
|
|
21
|
+
ELSE extends Narrowable
|
|
22
|
+
> = Extends<T, EXTENDS> extends true ? IF : ELSE;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { TupleToUnion } from "../type-conversion";
|
|
2
|
-
import { IsLiteral } from "./IsLiteral";
|
|
3
|
-
import { IsStringLiteral } from "./IsStringLiteral";
|
|
2
|
+
import { IsLiteral, IsStringLiteral } from "./IsLiteral";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
|
-
* **Includes
|
|
5
|
+
* **Includes**`<TSource, TValue>`
|
|
7
6
|
*
|
|
8
7
|
* Type utility which returns `true` or `false` based on whether `TValue` is found
|
|
9
8
|
* in `TSource`. Where `TSource` can be a string literal or an array of string literals.
|
|
@@ -13,7 +12,7 @@ import { IsStringLiteral } from "./IsStringLiteral";
|
|
|
13
12
|
* a type of `boolean`.
|
|
14
13
|
*/
|
|
15
14
|
export type Includes<
|
|
16
|
-
TSource extends string | string[],
|
|
15
|
+
TSource extends string | readonly string[],
|
|
17
16
|
TValue extends string
|
|
18
17
|
> = TSource extends string[]
|
|
19
18
|
? IsStringLiteral<TupleToUnion<TSource>> extends true
|
|
@@ -1,6 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { Narrowable } from "../Narrowable";
|
|
2
|
+
import { IsBooleanLiteral } from "./boolean";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* **IsStringLiteral**
|
|
6
|
+
*
|
|
7
|
+
* Type utility which returns true/false if the string a _string literal_ versus
|
|
8
|
+
* just the _string_ type.
|
|
9
|
+
*/
|
|
10
|
+
export type IsStringLiteral<T extends Narrowable> = [T] extends [string]
|
|
11
|
+
? string extends T
|
|
12
|
+
? false
|
|
13
|
+
: true
|
|
14
|
+
: false;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* **IfStringLiteral**
|
|
18
|
+
*
|
|
19
|
+
* Branch utility which returns `IF` type when `T` is a string literal and `ELSE` otherwise
|
|
20
|
+
*/
|
|
21
|
+
export type IfStringLiteral<T extends string, IF extends Narrowable, ELSE extends Narrowable> = [
|
|
22
|
+
IsStringLiteral<T>
|
|
23
|
+
] extends [true]
|
|
24
|
+
? IF
|
|
25
|
+
: ELSE;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* **IsNumericLiteral**
|
|
29
|
+
*
|
|
30
|
+
* Type utility which returns true/false if the numeric value a _numeric literal_ versus
|
|
31
|
+
* just the _number_ type.
|
|
32
|
+
*/
|
|
33
|
+
export type IsNumericLiteral<T extends number> = number extends T ? false : true;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* **IfNumericLiteral**
|
|
37
|
+
*
|
|
38
|
+
* Branch utility which returns `IF` type when `T` is a numeric literal and `ELSE` otherwise
|
|
39
|
+
*/
|
|
40
|
+
export type IfNumericLiteral<
|
|
41
|
+
T extends number,
|
|
42
|
+
IF extends Narrowable,
|
|
43
|
+
ELSE extends Narrowable
|
|
44
|
+
> = IsNumericLiteral<T> extends true ? IF : ELSE;
|
|
4
45
|
|
|
5
46
|
// [note on handling of boolean](https://stackoverflow.com/questions/74213646/detecting-type-literals-works-in-isolation-but-not-when-combined-with-other-lite/74213713#74213713)
|
|
6
47
|
|
|
@@ -43,7 +84,9 @@ export type IsOptionalLiteral<T> = [Exclude<T, undefined>] extends [string]
|
|
|
43
84
|
*
|
|
44
85
|
* Branch type utility with return `IF` when `T` is a _literal_ value and `ELSE` otherwise
|
|
45
86
|
*/
|
|
46
|
-
export type IfLiteral<T, IF, ELSE> = IsLiteral<T> extends true
|
|
87
|
+
export type IfLiteral<T, IF extends Narrowable, ELSE extends Narrowable> = IsLiteral<T> extends true
|
|
88
|
+
? IF
|
|
89
|
+
: ELSE;
|
|
47
90
|
|
|
48
91
|
/**
|
|
49
92
|
* **IfOptionalLiteral**
|
|
@@ -51,4 +94,8 @@ export type IfLiteral<T, IF, ELSE> = IsLiteral<T> extends true ? IF : ELSE;
|
|
|
51
94
|
* Branch type utility with return `IF` when `T` is a _literal_ value (with possibly
|
|
52
95
|
* the inclusion of _undefined_); otherwise returns the type `ELSE`
|
|
53
96
|
*/
|
|
54
|
-
export type IfOptionalLiteral<
|
|
97
|
+
export type IfOptionalLiteral<
|
|
98
|
+
T,
|
|
99
|
+
IF extends Narrowable,
|
|
100
|
+
ELSE extends Narrowable
|
|
101
|
+
> = IsOptionalLiteral<T> extends true ? IF : ELSE;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Narrowable } from "../Narrowable";
|
|
2
|
+
|
|
3
|
+
export type IsScalar<T extends Narrowable> = [T] extends [string]
|
|
4
|
+
? true
|
|
5
|
+
: [T] extends [number]
|
|
6
|
+
? true
|
|
7
|
+
: [T] extends [boolean]
|
|
8
|
+
? true
|
|
9
|
+
: false;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* **IfScalar**`<T, IF, ELSE>`
|
|
13
|
+
*
|
|
14
|
+
* Branch type utility which returns `IF` when `T` is a scalar value (aka, string, number, or boolean) and `ELSE` otherwise
|
|
15
|
+
*/
|
|
16
|
+
export type IfScalar<
|
|
17
|
+
T extends Narrowable,
|
|
18
|
+
IF extends Narrowable,
|
|
19
|
+
ELSE extends Narrowable
|
|
20
|
+
> = IsScalar<T> extends true ? IF : ELSE;
|
|
@@ -13,4 +13,8 @@ export type IsUndefined<T extends Narrowable> = T extends undefined ? true : fal
|
|
|
13
13
|
* Type utility which returns `IF` type when `T` is an _undefined_
|
|
14
14
|
* otherwise returns `ELSE` type.
|
|
15
15
|
*/
|
|
16
|
-
export type IfUndefined<
|
|
16
|
+
export type IfUndefined<
|
|
17
|
+
T,
|
|
18
|
+
IF extends Narrowable,
|
|
19
|
+
ELSE extends Narrowable
|
|
20
|
+
> = IsUndefined<T> extends true ? IF : ELSE;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NarrowlyContains } from "./array";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* **Or**`<T>`
|
|
5
|
+
*
|
|
6
|
+
* Takes an array of boolean values and produces a boolean OR across these values
|
|
7
|
+
*/
|
|
8
|
+
export type Or<T extends readonly boolean[]> = NarrowlyContains<true, T> extends true
|
|
9
|
+
? true
|
|
10
|
+
: NarrowlyContains<boolean, T> extends true
|
|
11
|
+
? boolean
|
|
12
|
+
: false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IsStringLiteral } from "src/types/boolean-logic";
|
|
2
2
|
import { Narrowable } from "../Narrowable";
|
|
3
3
|
/**
|
|
4
4
|
* **StartsWith**<TValue, TStartsWith>
|
|
@@ -9,17 +9,16 @@ import { Narrowable } from "../Narrowable";
|
|
|
9
9
|
* to a literal `true` or `false` but if either is not a literal that it will
|
|
10
10
|
* just resolve to `boolean` as the value can not be known at design time..
|
|
11
11
|
*/
|
|
12
|
-
export type StartsWith<
|
|
13
|
-
|
|
12
|
+
export type StartsWith<
|
|
13
|
+
TValue extends string,
|
|
14
|
+
TStartsWith extends string
|
|
15
|
+
> = IsStringLiteral<TStartsWith> extends true
|
|
16
|
+
? IsStringLiteral<TValue> extends true // both literals
|
|
14
17
|
? TValue extends `${TStartsWith}${string}`
|
|
15
|
-
?
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
>
|
|
20
|
-
: IfStringLiteral<TValue, false, boolean>
|
|
21
|
-
: false
|
|
22
|
-
: false;
|
|
18
|
+
? true
|
|
19
|
+
: false
|
|
20
|
+
: boolean
|
|
21
|
+
: boolean;
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* **IfStartsWith**<TValue, TStartsWith, IF, ELSE, MAYBE>
|
|
@@ -32,8 +31,8 @@ export type StartsWith<TValue extends unknown, TStartsWith extends unknown> = TV
|
|
|
32
31
|
* type and therefore the type is unknown at design time.
|
|
33
32
|
*/
|
|
34
33
|
export type IfStartsWith<
|
|
35
|
-
TValue extends
|
|
36
|
-
TStartsWith extends
|
|
34
|
+
TValue extends string,
|
|
35
|
+
TStartsWith extends string,
|
|
37
36
|
IF extends Narrowable,
|
|
38
37
|
ELSE extends Narrowable
|
|
39
38
|
> = StartsWith<TValue, TStartsWith> extends true
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Equal } from "./equivalency";
|
|
2
|
+
import { AfterFirst, First } from "../lists";
|
|
3
|
+
import { Narrowable } from "../Narrowable";
|
|
4
|
+
|
|
5
|
+
export type IsArray<T> = [T] extends [any[]] ? true : [T] extends [readonly any[]] ? true : false;
|
|
6
|
+
export type IsReadonlyArray<T> = T extends readonly any[] ? true : false;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* **IfArray**`<T, IF, ELSE>`
|
|
10
|
+
*
|
|
11
|
+
* Type utility which convert to type `IF` or `ELSE` based on whether `T` is an array
|
|
12
|
+
*/
|
|
13
|
+
export type IfArray<
|
|
14
|
+
T extends Narrowable,
|
|
15
|
+
IF extends Narrowable,
|
|
16
|
+
ELSE extends Narrowable
|
|
17
|
+
> = IsArray<T> extends true ? IF : ELSE;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* **IfArray**`<T, IF, ELSE>`
|
|
21
|
+
*
|
|
22
|
+
* Type utility which convert to type `IF` or `ELSE` based on whether `T` is a readonly array
|
|
23
|
+
*/
|
|
24
|
+
export type IfReadonlyArray<
|
|
25
|
+
T extends Narrowable,
|
|
26
|
+
IF extends Narrowable,
|
|
27
|
+
ELSE extends Narrowable
|
|
28
|
+
> = IsReadonlyArray<T> extends true ? IF : ELSE;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* **Contains**`<T, A>`
|
|
32
|
+
*
|
|
33
|
+
* Type utility which checks whether a type `T` exists within an array `A`. Result is
|
|
34
|
+
* `true` if `T` _extends_ any element in `A` making it match widely against `A`. If you
|
|
35
|
+
* prefer a narrower match you can use `NarrowlyContains<T,A>` instead.
|
|
36
|
+
*/
|
|
37
|
+
export type Contains<T extends Narrowable, A extends readonly any[]> = First<A> extends T
|
|
38
|
+
? true
|
|
39
|
+
: [] extends AfterFirst<A>
|
|
40
|
+
? false
|
|
41
|
+
: Contains<T, AfterFirst<A>>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* **NarrowlyContains**`<T, A>`
|
|
45
|
+
*
|
|
46
|
+
* Type utility which checks whether a type `T` exists within an array `A`. Result is
|
|
47
|
+
* `true` if `T` _extends_ any element in `A` making it match widely against `A`. If you
|
|
48
|
+
* prefer a wider match you can use `Contains<T,A>` instead.
|
|
49
|
+
*/
|
|
50
|
+
export type NarrowlyContains<T extends Narrowable, A extends readonly any[]> = Equal<
|
|
51
|
+
First<A>,
|
|
52
|
+
T
|
|
53
|
+
> extends true
|
|
54
|
+
? true
|
|
55
|
+
: [] extends AfterFirst<A>
|
|
56
|
+
? false
|
|
57
|
+
: NarrowlyContains<T, AfterFirst<A>>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Narrowable } from "../Narrowable";
|
|
2
|
+
|
|
3
|
+
export type IsBoolean<T> = T extends boolean ? true : false;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Type utility which returns `true` or `false` based on
|
|
7
|
+
* whether the type holds the narrow "true" type.
|
|
8
|
+
* ```ts
|
|
9
|
+
* // true
|
|
10
|
+
* type T = IsTrue<true>;
|
|
11
|
+
* // boolean
|
|
12
|
+
* type U = IsTrue<boolean>;
|
|
13
|
+
* // false
|
|
14
|
+
* type F = IsTrue<false>;
|
|
15
|
+
* type F2 = IsTrue<"false">;
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export type IsTrue<T extends Narrowable> = IsBoolean<T> extends true
|
|
19
|
+
? // is a boolean
|
|
20
|
+
T extends true
|
|
21
|
+
? true
|
|
22
|
+
: T extends false
|
|
23
|
+
? false
|
|
24
|
+
: unknown
|
|
25
|
+
: // not a boolean
|
|
26
|
+
false;
|
|
27
|
+
|
|
28
|
+
export type IsFalse<T extends Narrowable> = IsBoolean<T> extends true
|
|
29
|
+
? // is a boolean
|
|
30
|
+
T extends false
|
|
31
|
+
? true
|
|
32
|
+
: true extends T
|
|
33
|
+
? false
|
|
34
|
+
: // is of boolean type; therefore narrow type is unknown
|
|
35
|
+
unknown
|
|
36
|
+
: // not a boolean
|
|
37
|
+
false;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Type utility which checks for literal `true` value and then switches type
|
|
41
|
+
* to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
|
|
42
|
+
* is the wide type of `boolean`
|
|
43
|
+
*/
|
|
44
|
+
export type IfTrue<
|
|
45
|
+
T extends boolean,
|
|
46
|
+
IF extends Narrowable,
|
|
47
|
+
ELSE extends Narrowable,
|
|
48
|
+
MAYBE extends Narrowable
|
|
49
|
+
> = IsTrue<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Type utility which checks for literal `false` value and then switches type
|
|
53
|
+
* to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
|
|
54
|
+
* is the wide type of `boolean`
|
|
55
|
+
*/
|
|
56
|
+
export type IfFalse<
|
|
57
|
+
T extends Narrowable,
|
|
58
|
+
IF extends Narrowable,
|
|
59
|
+
ELSE extends Narrowable,
|
|
60
|
+
MAYBE extends Narrowable
|
|
61
|
+
> = IsFalse<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* **IsBooleanLiteral**
|
|
65
|
+
*
|
|
66
|
+
* Type utility which returns true/false if the boolean value is a _boolean literal_ versus
|
|
67
|
+
* just the wider _boolean_ type.
|
|
68
|
+
*/
|
|
69
|
+
export type IsBooleanLiteral<T extends Narrowable> = IsTrue<T> extends true
|
|
70
|
+
? true
|
|
71
|
+
: IsFalse<T> extends true
|
|
72
|
+
? true
|
|
73
|
+
: false;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* **IfBooleanLiteral**
|
|
77
|
+
*
|
|
78
|
+
* Branch utility which returns `IF` type when `T` is a boolean literal and `ELSE` otherwise
|
|
79
|
+
*/
|
|
80
|
+
export type IfBooleanLiteral<
|
|
81
|
+
T extends boolean,
|
|
82
|
+
IF extends Narrowable,
|
|
83
|
+
ELSE extends Narrowable
|
|
84
|
+
> = IsBooleanLiteral<T> extends true ? IF : ELSE;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Equal**`<X,Y>`
|
|
3
|
+
*
|
|
4
|
+
* Type utility which tests whether two types -- `X` and `Y` -- are exactly the same type
|
|
5
|
+
*/
|
|
6
|
+
export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
|
|
7
|
+
? true
|
|
8
|
+
: false;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* **NotEqual**`<X,Y>`
|
|
12
|
+
*
|
|
13
|
+
* Type utility which tests whether two types -- `X` and `Y` -- are _not_ exactly the same type
|
|
14
|
+
*/
|
|
15
|
+
export type NotEqual<X, Y> = true extends Equal<X, Y> ? false : true;
|