inferred-types 0.33.4 → 0.34.0
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 +156 -73
- 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 +12 -27
- package/src/runtime/type-checks/isUndefined.ts +1 -1
- package/src/runtime/type-checks/startsWith.ts +2 -2
- package/src/types/Mutable.ts +1 -1
- package/src/types/Narrowable.ts +1 -2
- package/src/types/{type-checks → boolean-logic}/EndsWith.ts +1 -1
- package/src/types/{type-checks → boolean-logic}/Extends.ts +3 -4
- package/src/types/{type-checks → boolean-logic}/Includes.ts +0 -0
- package/src/types/{type-checks → boolean-logic}/IsLiteral.ts +1 -1
- package/src/types/{type-checks → boolean-logic}/IsNumericLiteral.ts +0 -0
- package/src/types/{type-checks → boolean-logic}/IsScalar.ts +0 -0
- package/src/types/{type-checks → boolean-logic}/IsStringLiteral.ts +0 -0
- package/src/types/{type-checks → boolean-logic}/IsUndefined.ts +0 -0
- package/src/types/{type-checks → boolean-logic}/StartsWith.ts +1 -1
- 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 +76 -0
- package/src/types/{type-checks → boolean-logic}/index.ts +2 -1
- package/src/types/{type-checks → boolean-logic}/object.ts +0 -0
- package/src/types/{type-checks → boolean-logic}/string.ts +0 -0
- package/src/types/combinators/Or.ts +12 -0
- package/src/types/combinators/equivalency.ts +15 -0
- package/src/types/combinators/index.ts +2 -0
- package/src/types/dictionary/MapTo.ts +1 -1
- package/src/types/functions/LogicFunction.ts +1 -1
- package/src/types/index.ts +2 -1
- 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 +103 -2
- package/src/types/type-checks/IsBooleanLiteral.ts +0 -16
package/.vscode/settings.json
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -141,6 +141,97 @@ type Keys<T extends Record<string, any> | readonly string[], W extends string |
|
|
|
141
141
|
*/
|
|
142
142
|
type Length<T extends readonly any[]> = T["length"];
|
|
143
143
|
|
|
144
|
+
/**
|
|
145
|
+
* **Equal**`<X,Y>`
|
|
146
|
+
*
|
|
147
|
+
* Type utility which tests whether two types -- `X` and `Y` -- are exactly the same type
|
|
148
|
+
*/
|
|
149
|
+
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
|
|
150
|
+
/**
|
|
151
|
+
* **NotEqual**`<X,Y>`
|
|
152
|
+
*
|
|
153
|
+
* Type utility which tests whether two types -- `X` and `Y` -- are _not_ exactly the same type
|
|
154
|
+
*/
|
|
155
|
+
type NotEqual<X, Y> = true extends Equal<X, Y> ? false : true;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* **AfterFirst**`<T>`
|
|
159
|
+
*
|
|
160
|
+
* returns the elements in an array _after_ the first element
|
|
161
|
+
*/
|
|
162
|
+
type AfterFirst<T extends readonly any[]> = T extends readonly [any, ...any[]] ? T extends readonly [any, ...infer Rest] ? Rest : never : T;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* returns the first `string` value from an array of values
|
|
166
|
+
*/
|
|
167
|
+
type FirstString<T> = T extends [infer S extends string, ...unknown[]] ? S : never;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* **Split**`<T, SEP>`
|
|
171
|
+
*
|
|
172
|
+
* Splits a string literal `T` by string literal _separator_ `SEP`. The result is an array
|
|
173
|
+
* of string literals.
|
|
174
|
+
*/
|
|
175
|
+
type Split<T extends string, SEP extends string, ANSWER extends string[] = []> = string extends T ? string[] : T extends SEP ? ANSWER : T extends `${infer HEAD}${SEP}${infer TAIL}` ? Split<TAIL, SEP, [...ANSWER, HEAD]> : [...ANSWER, T];
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Get the type of a property of an object:
|
|
179
|
+
* ```ts
|
|
180
|
+
* const car = { make: "Chevy", model: "Malibu", }
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
type Get<T, K> = K extends `${infer FK}.${infer L}` ? FK extends keyof T ? Get<T[FK], L> : never : K extends keyof T ? T[K] : never;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* A union of types used in conjunction with the `literalValues()` function
|
|
187
|
+
* to produce a _narrow_ type definition of a passed in dictionary object.
|
|
188
|
+
*/
|
|
189
|
+
type Narrowable = string | number | boolean | symbol | object | undefined | void | null | {};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Create a union type based on a given property in an array of objects
|
|
193
|
+
* ```ts
|
|
194
|
+
* const data = [
|
|
195
|
+
* { id: 123, color: "blue" },
|
|
196
|
+
* { id: 456, color: "red" },
|
|
197
|
+
* ] as const;
|
|
198
|
+
* // 123 | 456
|
|
199
|
+
* type U = UniqueForProp<typeof data, "id">;
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
type UniqueForProp<T extends readonly Record<string, Narrowable>[], P extends string> = Readonly<Get<T[number], P>>;
|
|
203
|
+
|
|
204
|
+
type IsArray<T> = [T] extends [any[]] ? true : [T] extends [readonly any[]] ? true : false;
|
|
205
|
+
type IsReadonlyArray<T> = T extends readonly any[] ? true : false;
|
|
206
|
+
/**
|
|
207
|
+
* **IfArray**`<T, IF, ELSE>`
|
|
208
|
+
*
|
|
209
|
+
* Type utility which convert to type `IF` or `ELSE` based on whether `T` is an array
|
|
210
|
+
*/
|
|
211
|
+
type IfArray<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable> = IsArray<T> extends true ? IF : ELSE;
|
|
212
|
+
/**
|
|
213
|
+
* **IfArray**`<T, IF, ELSE>`
|
|
214
|
+
*
|
|
215
|
+
* Type utility which convert to type `IF` or `ELSE` based on whether `T` is a readonly array
|
|
216
|
+
*/
|
|
217
|
+
type IfReadonlyArray<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable> = IsReadonlyArray<T> extends true ? IF : ELSE;
|
|
218
|
+
/**
|
|
219
|
+
* **Contains**`<T, A>`
|
|
220
|
+
*
|
|
221
|
+
* Type utility which checks whether a type `T` exists within an array `A`. Result is
|
|
222
|
+
* `true` if `T` _extends_ any element in `A` making it match widely against `A`. If you
|
|
223
|
+
* prefer a narrower match you can use `NarrowlyContains<T,A>` instead.
|
|
224
|
+
*/
|
|
225
|
+
type Contains<T extends Narrowable, A extends readonly any[]> = First<A> extends T ? true : [] extends AfterFirst<A> ? false : Contains<T, AfterFirst<A>>;
|
|
226
|
+
/**
|
|
227
|
+
* **NarrowlyContains**`<T, A>`
|
|
228
|
+
*
|
|
229
|
+
* Type utility which checks whether a type `T` exists within an array `A`. Result is
|
|
230
|
+
* `true` if `T` _extends_ any element in `A` making it match widely against `A`. If you
|
|
231
|
+
* prefer a wider match you can use `Contains<T,A>` instead.
|
|
232
|
+
*/
|
|
233
|
+
type NarrowlyContains<T extends Narrowable, A extends readonly any[]> = Equal<First<A>, T> extends true ? true : [] extends AfterFirst<A> ? false : NarrowlyContains<T, AfterFirst<A>>;
|
|
234
|
+
|
|
144
235
|
/**
|
|
145
236
|
* Converts a Tuple type into a _union_ of the tuple elements
|
|
146
237
|
* ```ts
|
|
@@ -168,6 +259,34 @@ type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never] ? [] : [...Uni
|
|
|
168
259
|
|
|
169
260
|
type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
170
261
|
|
|
262
|
+
type IsBoolean<T> = T extends boolean ? true : false;
|
|
263
|
+
/**
|
|
264
|
+
* Type utility which returns `true` or `false` based on
|
|
265
|
+
* whether the type holds the narrow "true" type.
|
|
266
|
+
* ```ts
|
|
267
|
+
* // true
|
|
268
|
+
* type T = IsTrue<true>;
|
|
269
|
+
* // boolean
|
|
270
|
+
* type U = IsTrue<boolean>;
|
|
271
|
+
* // false
|
|
272
|
+
* type F = IsTrue<false>;
|
|
273
|
+
* type F2 = IsTrue<"false">;
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
type IsTrue<T extends Narrowable> = IsBoolean<T> extends true ? T extends true ? true : T extends false ? false : unknown : false;
|
|
277
|
+
type IsFalse<T extends Narrowable> = IsBoolean<T> extends true ? T extends false ? true : true extends T ? false : unknown : false;
|
|
278
|
+
/**
|
|
279
|
+
* Type utility which checks for literal `true` value and then switches type
|
|
280
|
+
* to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
|
|
281
|
+
* is the wide type of `boolean`
|
|
282
|
+
*/
|
|
283
|
+
type IfTrue<T, IF, ELSE, MAYBE> = IsTrue<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
|
|
284
|
+
/**
|
|
285
|
+
* Type utility which checks for literal `false` value and then switches type
|
|
286
|
+
* to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
|
|
287
|
+
* is the wide type of `boolean`
|
|
288
|
+
*/
|
|
289
|
+
type IfFalse<T, IF, ELSE, MAYBE> = IsFalse<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
|
|
171
290
|
/**
|
|
172
291
|
* **IsBooleanLiteral**
|
|
173
292
|
*
|
|
@@ -264,12 +383,6 @@ type IsScalar<T> = [T] extends [string] ? true : [T] extends [number] ? true : [
|
|
|
264
383
|
*/
|
|
265
384
|
type IfScalar<T, IF, ELSE> = IsScalar<T> extends true ? IF : ELSE;
|
|
266
385
|
|
|
267
|
-
/**
|
|
268
|
-
* A union of types used in conjunction with the `literalValues()` function
|
|
269
|
-
* to produce a _narrow_ type definition of a passed in dictionary object.
|
|
270
|
-
*/
|
|
271
|
-
type Narrowable = string | number | boolean | symbol | object | undefined | void | null | {};
|
|
272
|
-
|
|
273
386
|
/**
|
|
274
387
|
* **IsUndefined**
|
|
275
388
|
*
|
|
@@ -285,11 +398,11 @@ type IsUndefined<T extends Narrowable> = T extends undefined ? true : false;
|
|
|
285
398
|
type IfUndefined<T, IF, ELSE> = IsUndefined<T> extends true ? IF : ELSE;
|
|
286
399
|
|
|
287
400
|
/**
|
|
288
|
-
* **Extends
|
|
401
|
+
* **Extends**`<T, EXTENDS>`
|
|
289
402
|
*
|
|
290
|
-
* Boolean type utility which returns `true` if `
|
|
403
|
+
* Boolean type utility which returns `true` if `T` _extends_ `EXTENDS`.
|
|
291
404
|
*/
|
|
292
|
-
type Extends<
|
|
405
|
+
type Extends<T, EXTENDS> = T extends EXTENDS ? true : false;
|
|
293
406
|
/**
|
|
294
407
|
* **IfExtends**
|
|
295
408
|
*
|
|
@@ -1212,14 +1325,6 @@ O extends (...args: any[]) => any = (...args: any[]) => any> = SimplifyObject<{
|
|
|
1212
1325
|
[K in keyof T]: T[K] extends O ? T[K] extends (...args: infer A) => any ? Record<K, (...args: A) => R> : Record<K, T[K]> : Record<K, T[K]>;
|
|
1213
1326
|
}[keyof T]>;
|
|
1214
1327
|
|
|
1215
|
-
/**
|
|
1216
|
-
* Get the type of a property of an object:
|
|
1217
|
-
* ```ts
|
|
1218
|
-
* const car = { make: "Chevy", model: "Malibu", }
|
|
1219
|
-
* ```
|
|
1220
|
-
*/
|
|
1221
|
-
type Get<T, K> = K extends `${infer FK}.${infer L}` ? FK extends keyof T ? Get<T[FK], L> : never : K extends keyof T ? T[K] : never;
|
|
1222
|
-
|
|
1223
1328
|
/**
|
|
1224
1329
|
* Expresses whether an option is "opt" (optional) or "req" (required)
|
|
1225
1330
|
*/
|
|
@@ -1544,7 +1649,7 @@ type FinalReturn<T extends any> = T extends (...args: any[]) => any ? FinalRetur
|
|
|
1544
1649
|
/**
|
|
1545
1650
|
* A function which returns a boolean value
|
|
1546
1651
|
*/
|
|
1547
|
-
type LogicFunction<T extends any[]> = (...args: T) => boolean;
|
|
1652
|
+
type LogicFunction<T extends readonly any[]> = (...args: T) => boolean;
|
|
1548
1653
|
|
|
1549
1654
|
type DictFromKv<T extends readonly {
|
|
1550
1655
|
key: string;
|
|
@@ -1594,37 +1699,11 @@ type KvFrom<T extends object> = Array<{
|
|
|
1594
1699
|
type KvTuple<T, K extends keyof T> = [K, Record<K, T[K]>];
|
|
1595
1700
|
|
|
1596
1701
|
/**
|
|
1597
|
-
* **
|
|
1702
|
+
* **Or**`<T>`
|
|
1598
1703
|
*
|
|
1599
|
-
*
|
|
1704
|
+
* Takes an array of boolean values and produces a boolean OR across these values
|
|
1600
1705
|
*/
|
|
1601
|
-
type
|
|
1602
|
-
|
|
1603
|
-
/**
|
|
1604
|
-
* returns the first `string` value from an array of values
|
|
1605
|
-
*/
|
|
1606
|
-
type FirstString<T> = T extends [infer S extends string, ...unknown[]] ? S : never;
|
|
1607
|
-
|
|
1608
|
-
/**
|
|
1609
|
-
* **Split**`<T, SEP>`
|
|
1610
|
-
*
|
|
1611
|
-
* Splits a string literal `T` by string literal _separator_ `SEP`. The result is an array
|
|
1612
|
-
* of string literals.
|
|
1613
|
-
*/
|
|
1614
|
-
type Split<T extends string, SEP extends string, ANSWER extends string[] = []> = string extends T ? string[] : T extends SEP ? ANSWER : T extends `${infer HEAD}${SEP}${infer TAIL}` ? Split<TAIL, SEP, [...ANSWER, HEAD]> : [...ANSWER, T];
|
|
1615
|
-
|
|
1616
|
-
/**
|
|
1617
|
-
* Create a union type based on a given property in an array of objects
|
|
1618
|
-
* ```ts
|
|
1619
|
-
* const data = [
|
|
1620
|
-
* { id: 123, color: "blue" },
|
|
1621
|
-
* { id: 456, color: "red" },
|
|
1622
|
-
* ] as const;
|
|
1623
|
-
* // 123 | 456
|
|
1624
|
-
* type U = UniqueForProp<typeof data, "id">;
|
|
1625
|
-
* ```
|
|
1626
|
-
*/
|
|
1627
|
-
type UniqueForProp<T extends readonly Record<string, Narrowable>[], P extends string> = Readonly<Get<T[number], P>>;
|
|
1706
|
+
type Or<T extends readonly boolean[]> = NarrowlyContains<true, T> extends true ? true : NarrowlyContains<boolean, T> extends true ? boolean : false;
|
|
1628
1707
|
|
|
1629
1708
|
type DictArrayFilterCallback<K extends keyof T, T extends object, R extends true | false> = (key: K, value: Pick<T, K>) => R;
|
|
1630
1709
|
/**
|
|
@@ -1738,13 +1817,7 @@ declare const api: <N extends Narrowable, TPrivate extends Readonly<Record<any,
|
|
|
1738
1817
|
*/
|
|
1739
1818
|
declare const and: <T extends any[]>(...ops: readonly LogicFunction<T>[]) => LogicFunction<T>;
|
|
1740
1819
|
|
|
1741
|
-
|
|
1742
|
-
* Groups a number of "logic functions" together by combining their results using
|
|
1743
|
-
* the logical **OR** operator.
|
|
1744
|
-
*
|
|
1745
|
-
* **Note:** a "logic function" is any function which returns a boolean
|
|
1746
|
-
*/
|
|
1747
|
-
declare const or: <T extends any[]>(...ops: LogicFunction<T>[]) => LogicFunction<T>;
|
|
1820
|
+
declare function or<O extends readonly boolean[]>(...conditions: O): Or<O>;
|
|
1748
1821
|
|
|
1749
1822
|
/**
|
|
1750
1823
|
* Groups a number of "logic functions" together by combining their results using
|
|
@@ -2165,10 +2238,15 @@ type SuggestNumeric<T extends number> = T | (number & {});
|
|
|
2165
2238
|
type Condition<TInput extends Narrowable, TResult extends boolean> = (input: TInput) => TResult;
|
|
2166
2239
|
declare const condition: <TInput extends Narrowable, C extends Condition<Narrowable, boolean>>(c: C, input: TInput) => boolean;
|
|
2167
2240
|
|
|
2168
|
-
type IsArray<T> = T extends any[] ? true : false;
|
|
2169
2241
|
declare function isArray<T>(i: T): IsArray<T>;
|
|
2242
|
+
/**
|
|
2243
|
+
* **ifArray**(T, IF, ELSE)
|
|
2244
|
+
*
|
|
2245
|
+
* A utility which evaluates a type `T` for whether it is an array and then
|
|
2246
|
+
*/
|
|
2247
|
+
declare function ifArray<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, isAnArray: <N extends T & readonly any[]>(arr: N) => IF, isNotAnArray: <N extends Exclude<T, any[]>>(nonArr: N) => ELSE): IfArray<T, IF, ELSE>;
|
|
2248
|
+
declare function ifArrayPartial<T extends Narrowable>(): <IF extends Narrowable, ELSE extends Narrowable>(isAnArray: <N extends T & readonly any[]>(arr: N) => IF, isNotAnArray: <N_1 extends Exclude<T, any[]>>(nonArr: N_1) => ELSE) => <V extends T>(val: V) => IfArray<V, IF, ELSE>;
|
|
2170
2249
|
|
|
2171
|
-
type IsBoolean<T> = T extends boolean ? true : false;
|
|
2172
2250
|
/**
|
|
2173
2251
|
* Runtime and type checks whether a variable is a boolean value.
|
|
2174
2252
|
*/
|
|
@@ -2186,8 +2264,23 @@ declare function isBoolean<T extends any>(i: T): IsBoolean<T>;
|
|
|
2186
2264
|
*/
|
|
2187
2265
|
declare function ifBoolean<T, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE): IsBoolean<T> extends true ? IF : ELSE;
|
|
2188
2266
|
|
|
2189
|
-
type IsFalse<T extends Narrowable> = IsBoolean<T> extends true ? T extends false ? true : true extends T ? false : unknown : false;
|
|
2190
2267
|
declare function isFalse<T>(i: T): IsFalse<T>;
|
|
2268
|
+
/**
|
|
2269
|
+
* **ifTrue**
|
|
2270
|
+
*
|
|
2271
|
+
* Strongly type-aware conditional statement which checks whether a value is
|
|
2272
|
+
* a _true_ and returns one of two values (strongly typed) based on the evaluation
|
|
2273
|
+
* of this criteria.
|
|
2274
|
+
*
|
|
2275
|
+
* @param val the value being tested
|
|
2276
|
+
* @param ifVal the value (strongly typed) returned if val is _true_ value
|
|
2277
|
+
* @param elseVal the value (strongly typed) returned if val is NOT a _true_ value
|
|
2278
|
+
*
|
|
2279
|
+
* Note: at runtime there's no way to distinguish if the value was widely or loosely
|
|
2280
|
+
* typed so unlike the type utility there is no "MAYBE" state but if a wide type if
|
|
2281
|
+
* encountered the _type_ will the union of `IF` and `ELSE`.
|
|
2282
|
+
*/
|
|
2283
|
+
declare function ifFalse<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IfFalse<T, IF, ELSE, IF | ELSE>;
|
|
2191
2284
|
|
|
2192
2285
|
type IsFunction<T> = T extends FunctionType ? true : false;
|
|
2193
2286
|
type HybridFunction<TProps extends {}> = (<TArgs extends any[]>(...args: TArgs) => any) & TProps;
|
|
@@ -2287,20 +2380,6 @@ declare function ifString<T extends Narrowable, IF extends Narrowable, ELSE exte
|
|
|
2287
2380
|
|
|
2288
2381
|
declare function isSymbol<T>(i: T): T extends symbol ? true : false;
|
|
2289
2382
|
|
|
2290
|
-
/**
|
|
2291
|
-
* Type utility which returns `true` or `false` based on
|
|
2292
|
-
* whether the type holds the narrow "true" type.
|
|
2293
|
-
* ```ts
|
|
2294
|
-
* // true
|
|
2295
|
-
* type T = IsTrue<true>;
|
|
2296
|
-
* // unknown
|
|
2297
|
-
* type U = IsTrue<boolean>;
|
|
2298
|
-
* // false
|
|
2299
|
-
* type F = IsTrue<false>;
|
|
2300
|
-
* type F2 = IsTrue<"false">;
|
|
2301
|
-
* ```
|
|
2302
|
-
*/
|
|
2303
|
-
type IsTrue<T> = IsBoolean<T> extends true ? T extends true ? true : T extends false ? false : unknown : false;
|
|
2304
2383
|
/**
|
|
2305
2384
|
* Run-time and type checking of whether a variable is `true`.
|
|
2306
2385
|
*/
|
|
@@ -2315,8 +2394,12 @@ declare function isTrue<T extends Narrowable>(i: T): IsTrue<T>;
|
|
|
2315
2394
|
* @param val the value being tested
|
|
2316
2395
|
* @param ifVal the value (strongly typed) returned if val is _true_ value
|
|
2317
2396
|
* @param elseVal the value (strongly typed) returned if val is NOT a _true_ value
|
|
2397
|
+
*
|
|
2398
|
+
* Note: at runtime there's no way to distinguish if the value was widely or loosely
|
|
2399
|
+
* typed so unlike the type utility there is no "MAYBE" state but if a wide type if
|
|
2400
|
+
* encountered the _type_ will the union of `IF` and `ELSE`.
|
|
2318
2401
|
*/
|
|
2319
|
-
declare function ifTrue<T extends Narrowable, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE):
|
|
2402
|
+
declare function ifTrue<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IfTrue<T, IF, ELSE, IF | ELSE>;
|
|
2320
2403
|
|
|
2321
2404
|
declare function isUndefined<T extends Narrowable>(i: T): undefined extends T ? true : false;
|
|
2322
2405
|
/**
|
|
@@ -2440,4 +2523,4 @@ interface IFluentConfigurator<C> {
|
|
|
2440
2523
|
*/
|
|
2441
2524
|
declare function FluentConfigurator<I>(initial?: I): IFluentConfigurator<{}>;
|
|
2442
2525
|
|
|
2443
|
-
export { AfterFirst, AllCaps, Alpha, AlphaNumeric, AnyFunction, Api, ApiFunction, ApiValue, AppendToDictionary, AppendToObject, ArrConcat, Array$1 as Array, ArrayConverter, AsArray, AsFinalizedConfig, AssertExtends, Box, BoxValue, BoxedFnParams, BoxedReturn, Bracket, Break, CamelCase, CapitalizeWords, Cardinality, Cardinality0, Cardinality1, CardinalityExplicit, CardinalityFilter0, CardinalityFilter1, CardinalityIn, CardinalityInput, CardinalityNode, CardinalityOut, CardinalityTuple, ClosingBracket, Condition, ConditionFilter, Configurator, ConfiguredMap, Constructor, DEFAULT_MANY_TO_ONE_MAPPING, DEFAULT_ONE_TO_MANY_MAPPING, DEFAULT_ONE_TO_ONE_MAPPING, DashToSnake, DashUppercase, Dasherize, DecomposeMapConfig, DefaultManyToOneMapping, DefaultOneToManyMapping, DefaultOneToOneMapping, DefinePropertiesApi, DictArrApi, DictArray, DictArrayFilterCallback, DictArrayKv, DictChangeValue, DictFromKv, DictKvTuple, DictPartialApplication, DictPrependWithFn, DictReturnValues, DomainName, DynamicRule, DynamicRuleSet, Email, EndsWith, EnumValues, ExpandRecursively, ExpectExtends, ExplicitFunction, Extends, FilterContains, FilterDefn, FilterEnds, FilterEquals, FilterFn, FilterGreaterThan, FilterIs, FilterLessThan, FilterNotEqual, FilterStarts, FinalReturn, FinalizedMapConfig, First, FirstKey, FirstKeyValue, FirstOfEach, FirstOrUndefined, FirstString, FluentConfigurator, FluentFunction, FnShape, FromDictArray, FullyQualifiedUrl, FunctionType, GeneralDictionary, Get, HasUppercase, HybridFunction, IConfigurator, IFluentConfigurator, If, IfBooleanLiteral, IfExtends, IfExtendsThen, IfLiteral, IfNumericLiteral, IfObject, IfOptionalLiteral, IfScalar, IfStartsWith, IfStringLiteral, IfUndefined, Include, Includes, IntersectingKeys, Ipv4, IsArray, IsBoolean, IsBooleanLiteral, IsCapitalized, IsFalse, IsFunction, IsLiteral, IsNull, IsNumber, IsNumericLiteral, IsObject, IsOptionalLiteral, IsScalar, IsStringLiteral, IsTrue, IsUndefined, KebabCase, KeyValue, KeyedRecord, Keys, KeysWithValue, KvFrom, KvTuple, LastInUnion, LeftWhitespace, Length, LogicFunction, LogicalCombinator, LowerAllCaps, LowerAlpha, ManyToMany, ManyToOne, ManyToZero, MapCard, MapCardinality, MapCardinalityFrom, MapCardinalityIllustrated, MapConfig, MapFn, MapFnInput, MapFnOutput, MapIR, MapInput, MapInputFrom, MapOR, MapOutput, MapOutputFrom, MapTo, Mapper, MapperApi, MaybeFalse, MaybeTrue, Mutable, MutableProps, NarrowBox, Narrowable, NetworkProtocol, NonAlpha, NonNumericKeys, NonStringKeys, Not, NotFilter, Numeric, NumericFilter, NumericKeys, NumericString, ObjectType, OneToMany, OneToOne, OneToZero, Opaque, OpeningBracket, OptRequired, OptionalKeys, OptionalProps, Parenthesis, PascalCase, Pluralize, PrivateKey, PrivateKeys, PublicKeys, Punctuation, PureFluentApi, RelativeUrl, Replace, RequireProps, RequiredKeys, RequiredProps, Retain, RightWhitespace, RuleDefinition, RuntimeProp, RuntimeType, SameKeys, SecondOfEach, SimpleFunction, SimplifyObject, SnakeCase, SpecialCharacters, Split, StartsWith, StringDelimiter, StringFilter, StringKeys, StringLength, Suggest, SuggestNumeric, ToFluent, Transformer, Trim, TrimLeft, TrimRight, TupleToUnion, Type, TypeApi, TypeDefault, TypeDefinition, TypeGuard, TypeOptions, Unbox, UndefinedArrayIsUnknown, UndefinedTreatment, UndefinedValue, UnionToIntersection, UnionToTuple, UniqueDictionary, UniqueForProp, Uniqueness, UnwrapNot, UpperAlpha, UrlBuilder, VariableName, Where, WhereNot, Whitespace, Widen, WithNumericKeys, WithStringKeys, WithValue, ZeroToMany, ZeroToOne, ZeroToZero, ZipCode, and, api, arrayToKeyLookup, arrayToObject, asArray, box, condition, createFnWithProps, defineProperties, defineType, dictArr, dictToKv, dictionaryTransform, entries, filter, filterDictArray, fnWithProps, groupBy, idLiteral, idTypeGuard, identity, ifBoolean, ifNull, ifNumber, ifString, ifTrue, ifUndefined, isArray, isBoolean, isBox, isFalse, isFunction, isNotFilter, isNull, isNumber, isNumericFilter, isObject, isString, isSymbol, isTrue, isType, isUndefined, keys, kindLiteral, kv, kvToDict, literal, mapTo, mapToDict, mapToFn, mapValues, nameLiteral, not, or, readonlyFnWithProps, ruleSet, strArrayToDict, type, typeApi, unbox, withValue };
|
|
2526
|
+
export { AfterFirst, AllCaps, Alpha, AlphaNumeric, AnyFunction, Api, ApiFunction, ApiValue, AppendToDictionary, AppendToObject, ArrConcat, Array$1 as Array, ArrayConverter, AsArray, AsFinalizedConfig, AssertExtends, Box, BoxValue, BoxedFnParams, BoxedReturn, Bracket, Break, CamelCase, CapitalizeWords, Cardinality, Cardinality0, Cardinality1, CardinalityExplicit, CardinalityFilter0, CardinalityFilter1, CardinalityIn, CardinalityInput, CardinalityNode, CardinalityOut, CardinalityTuple, ClosingBracket, Condition, ConditionFilter, Configurator, ConfiguredMap, Constructor, Contains, DEFAULT_MANY_TO_ONE_MAPPING, DEFAULT_ONE_TO_MANY_MAPPING, DEFAULT_ONE_TO_ONE_MAPPING, DashToSnake, DashUppercase, Dasherize, DecomposeMapConfig, DefaultManyToOneMapping, DefaultOneToManyMapping, DefaultOneToOneMapping, DefinePropertiesApi, DictArrApi, DictArray, DictArrayFilterCallback, DictArrayKv, DictChangeValue, DictFromKv, DictKvTuple, DictPartialApplication, DictPrependWithFn, DictReturnValues, DomainName, DynamicRule, DynamicRuleSet, Email, EndsWith, EnumValues, Equal, ExpandRecursively, ExpectExtends, ExplicitFunction, Extends, FilterContains, FilterDefn, FilterEnds, FilterEquals, FilterFn, FilterGreaterThan, FilterIs, FilterLessThan, FilterNotEqual, FilterStarts, FinalReturn, FinalizedMapConfig, First, FirstKey, FirstKeyValue, FirstOfEach, FirstOrUndefined, FirstString, FluentConfigurator, FluentFunction, FnShape, FromDictArray, FullyQualifiedUrl, FunctionType, GeneralDictionary, Get, HasUppercase, HybridFunction, IConfigurator, IFluentConfigurator, If, IfArray, IfBooleanLiteral, IfExtends, IfExtendsThen, IfFalse, IfLiteral, IfNumericLiteral, IfObject, IfOptionalLiteral, IfReadonlyArray, IfScalar, IfStartsWith, IfStringLiteral, IfTrue, IfUndefined, Include, Includes, IntersectingKeys, Ipv4, IsArray, IsBoolean, IsBooleanLiteral, IsCapitalized, IsFalse, IsFunction, IsLiteral, IsNull, IsNumber, IsNumericLiteral, IsObject, IsOptionalLiteral, IsReadonlyArray, IsScalar, IsStringLiteral, IsTrue, IsUndefined, KebabCase, KeyValue, KeyedRecord, Keys, KeysWithValue, KvFrom, KvTuple, LastInUnion, LeftWhitespace, Length, LogicFunction, LogicalCombinator, LowerAllCaps, LowerAlpha, ManyToMany, ManyToOne, ManyToZero, MapCard, MapCardinality, MapCardinalityFrom, MapCardinalityIllustrated, MapConfig, MapFn, MapFnInput, MapFnOutput, MapIR, MapInput, MapInputFrom, MapOR, MapOutput, MapOutputFrom, MapTo, Mapper, MapperApi, MaybeFalse, MaybeTrue, Mutable, MutableProps, NarrowBox, Narrowable, NarrowlyContains, NetworkProtocol, NonAlpha, NonNumericKeys, NonStringKeys, Not, NotEqual, NotFilter, Numeric, NumericFilter, NumericKeys, NumericString, ObjectType, OneToMany, OneToOne, OneToZero, Opaque, OpeningBracket, OptRequired, OptionalKeys, OptionalProps, Or, Parenthesis, PascalCase, Pluralize, PrivateKey, PrivateKeys, PublicKeys, Punctuation, PureFluentApi, RelativeUrl, Replace, RequireProps, RequiredKeys, RequiredProps, Retain, RightWhitespace, RuleDefinition, RuntimeProp, RuntimeType, SameKeys, SecondOfEach, SimpleFunction, SimplifyObject, SnakeCase, SpecialCharacters, Split, StartsWith, StringDelimiter, StringFilter, StringKeys, StringLength, Suggest, SuggestNumeric, ToFluent, Transformer, Trim, TrimLeft, TrimRight, TupleToUnion, Type, TypeApi, TypeDefault, TypeDefinition, TypeGuard, TypeOptions, Unbox, UndefinedArrayIsUnknown, UndefinedTreatment, UndefinedValue, UnionToIntersection, UnionToTuple, UniqueDictionary, UniqueForProp, Uniqueness, UnwrapNot, UpperAlpha, UrlBuilder, VariableName, Where, WhereNot, Whitespace, Widen, WithNumericKeys, WithStringKeys, WithValue, ZeroToMany, ZeroToOne, ZeroToZero, ZipCode, and, api, arrayToKeyLookup, arrayToObject, asArray, box, condition, createFnWithProps, defineProperties, defineType, dictArr, dictToKv, dictionaryTransform, entries, filter, filterDictArray, fnWithProps, groupBy, idLiteral, idTypeGuard, identity, ifArray, ifArrayPartial, ifBoolean, ifFalse, ifNull, ifNumber, ifString, ifTrue, ifUndefined, isArray, isBoolean, isBox, isFalse, isFunction, isNotFilter, isNull, isNumber, isNumericFilter, isObject, isString, isSymbol, isTrue, isType, isUndefined, keys, kindLiteral, kv, kvToDict, literal, mapTo, mapToDict, mapToFn, mapValues, nameLiteral, not, or, readonlyFnWithProps, ruleSet, strArrayToDict, type, typeApi, unbox, withValue };
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,10 @@ __export(src_exports, {
|
|
|
48
48
|
idLiteral: () => idLiteral,
|
|
49
49
|
idTypeGuard: () => idTypeGuard,
|
|
50
50
|
identity: () => identity,
|
|
51
|
+
ifArray: () => ifArray,
|
|
52
|
+
ifArrayPartial: () => ifArrayPartial,
|
|
51
53
|
ifBoolean: () => ifBoolean,
|
|
54
|
+
ifFalse: () => ifFalse,
|
|
52
55
|
ifNull: () => ifNull,
|
|
53
56
|
ifNumber: () => ifNumber,
|
|
54
57
|
ifString: () => ifString,
|
|
@@ -151,12 +154,9 @@ var and = (...ops) => {
|
|
|
151
154
|
};
|
|
152
155
|
|
|
153
156
|
// src/runtime/combinators/or.ts
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
};
|
|
158
|
-
return fn;
|
|
159
|
-
};
|
|
157
|
+
function or(...conditions) {
|
|
158
|
+
return conditions.some((v) => v === true) ? true : false;
|
|
159
|
+
}
|
|
160
160
|
|
|
161
161
|
// src/runtime/combinators/not.ts
|
|
162
162
|
var not = (op) => {
|
|
@@ -175,6 +175,14 @@ var condition = (c, input) => {
|
|
|
175
175
|
function isArray(i) {
|
|
176
176
|
return Array.isArray(i) === true;
|
|
177
177
|
}
|
|
178
|
+
function ifArray(val, isAnArray, isNotAnArray) {
|
|
179
|
+
return isArray(val) ? isAnArray(val) : isNotAnArray(val);
|
|
180
|
+
}
|
|
181
|
+
function ifArrayPartial() {
|
|
182
|
+
return (isAnArray, isNotAnArray) => {
|
|
183
|
+
return (val) => ifArray(val, isAnArray, isNotAnArray);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
178
186
|
|
|
179
187
|
// src/runtime/type-checks/isBoolean.ts
|
|
180
188
|
function isBoolean(i) {
|
|
@@ -188,6 +196,9 @@ function ifBoolean(val, ifVal, elseVal) {
|
|
|
188
196
|
function isFalse(i) {
|
|
189
197
|
return typeof i === "boolean" && !i;
|
|
190
198
|
}
|
|
199
|
+
function ifFalse(val, ifVal, elseVal) {
|
|
200
|
+
return isFalse(val) ? ifVal : elseVal;
|
|
201
|
+
}
|
|
191
202
|
|
|
192
203
|
// src/runtime/type-checks/isFunction.ts
|
|
193
204
|
function isFunction(input) {
|
|
@@ -795,7 +806,10 @@ function literal(obj) {
|
|
|
795
806
|
idLiteral,
|
|
796
807
|
idTypeGuard,
|
|
797
808
|
identity,
|
|
809
|
+
ifArray,
|
|
810
|
+
ifArrayPartial,
|
|
798
811
|
ifBoolean,
|
|
812
|
+
ifFalse,
|
|
799
813
|
ifNull,
|
|
800
814
|
ifNumber,
|
|
801
815
|
ifString,
|
package/dist/index.mjs
CHANGED
|
@@ -58,12 +58,9 @@ var and = (...ops) => {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// src/runtime/combinators/or.ts
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
};
|
|
65
|
-
return fn;
|
|
66
|
-
};
|
|
61
|
+
function or(...conditions) {
|
|
62
|
+
return conditions.some((v) => v === true) ? true : false;
|
|
63
|
+
}
|
|
67
64
|
|
|
68
65
|
// src/runtime/combinators/not.ts
|
|
69
66
|
var not = (op) => {
|
|
@@ -82,6 +79,14 @@ var condition = (c, input) => {
|
|
|
82
79
|
function isArray(i) {
|
|
83
80
|
return Array.isArray(i) === true;
|
|
84
81
|
}
|
|
82
|
+
function ifArray(val, isAnArray, isNotAnArray) {
|
|
83
|
+
return isArray(val) ? isAnArray(val) : isNotAnArray(val);
|
|
84
|
+
}
|
|
85
|
+
function ifArrayPartial() {
|
|
86
|
+
return (isAnArray, isNotAnArray) => {
|
|
87
|
+
return (val) => ifArray(val, isAnArray, isNotAnArray);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
85
90
|
|
|
86
91
|
// src/runtime/type-checks/isBoolean.ts
|
|
87
92
|
function isBoolean(i) {
|
|
@@ -95,6 +100,9 @@ function ifBoolean(val, ifVal, elseVal) {
|
|
|
95
100
|
function isFalse(i) {
|
|
96
101
|
return typeof i === "boolean" && !i;
|
|
97
102
|
}
|
|
103
|
+
function ifFalse(val, ifVal, elseVal) {
|
|
104
|
+
return isFalse(val) ? ifVal : elseVal;
|
|
105
|
+
}
|
|
98
106
|
|
|
99
107
|
// src/runtime/type-checks/isFunction.ts
|
|
100
108
|
function isFunction(input) {
|
|
@@ -701,7 +709,10 @@ export {
|
|
|
701
709
|
idLiteral,
|
|
702
710
|
idTypeGuard,
|
|
703
711
|
identity,
|
|
712
|
+
ifArray,
|
|
713
|
+
ifArrayPartial,
|
|
704
714
|
ifBoolean,
|
|
715
|
+
ifFalse,
|
|
705
716
|
ifNull,
|
|
706
717
|
ifNumber,
|
|
707
718
|
ifString,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inferred-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"description": "Functions which provide useful type inference on TS projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ken Snyder<ken@ken.net>",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
"watch:bundle": "npx tsup src/index.ts --dts --format=esm,cjs --watch",
|
|
23
23
|
"clean": "rimraf dist/**/*",
|
|
24
24
|
"lint": "eslint src/**/*.ts --fix && tsc --noEmit ",
|
|
25
|
-
"lint:full": "eslint src/**/*.ts && eslint
|
|
25
|
+
"lint:full": "eslint src/**/*.ts && eslint tests/**/*.ts && tsc --noEmit",
|
|
26
26
|
"test": "vitest",
|
|
27
27
|
"test:ci": "vitest run",
|
|
28
28
|
"audit:fix": "pnpm audit --fix",
|
|
29
|
-
"release": "run-s lint release:latest test:ci audit:fix release:bump",
|
|
29
|
+
"release": "run-s lint:full release:latest test:ci audit:fix release:bump",
|
|
30
30
|
"release:latest": "pnpm install",
|
|
31
31
|
"release:bump": "bumpp"
|
|
32
32
|
},
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Or } from "src/types/combinators/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 Narrowable, 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`.
|
|
@@ -41,7 +18,15 @@ export function isTrue<T extends Narrowable>(i: T) {
|
|
|
41
18
|
* @param val the value being tested
|
|
42
19
|
* @param ifVal the value (strongly typed) returned if val is _true_ value
|
|
43
20
|
* @param elseVal the value (strongly typed) returned if val is NOT a _true_ value
|
|
21
|
+
*
|
|
22
|
+
* Note: at runtime there's no way to distinguish if the value was widely or loosely
|
|
23
|
+
* typed so unlike the type utility there is no "MAYBE" state but if a wide type if
|
|
24
|
+
* encountered the _type_ will the union of `IF` and `ELSE`.
|
|
44
25
|
*/
|
|
45
|
-
export function ifTrue<T extends Narrowable, IF
|
|
46
|
-
|
|
26
|
+
export function ifTrue<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(
|
|
27
|
+
val: T,
|
|
28
|
+
ifVal: IF,
|
|
29
|
+
elseVal: ELSE
|
|
30
|
+
) {
|
|
31
|
+
return (isTrue(val) ? ifVal : elseVal) as IfTrue<T, IF, ELSE, IF | ELSE>;
|
|
47
32
|
}
|
|
@@ -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,5 @@
|
|
|
1
|
-
import { IfStartsWith, StartsWith } from "src/types/
|
|
2
|
-
import { IfUndefined } from "src/types/
|
|
1
|
+
import { IfStartsWith, StartsWith } from "src/types/boolean-logic";
|
|
2
|
+
import { IfUndefined } from "src/types/boolean-logic/IsUndefined";
|
|
3
3
|
import { createFnWithProps } from "../createFnWithProps";
|
|
4
4
|
import { box, Box } from "../literals";
|
|
5
5
|
import { ifTrue } from "./isTrue";
|
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 | {};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* **Extends
|
|
2
|
+
* **Extends**`<T, EXTENDS>`
|
|
3
3
|
*
|
|
4
|
-
* Boolean type utility which returns `true` if `
|
|
4
|
+
* Boolean type utility which returns `true` if `T` _extends_ `EXTENDS`.
|
|
5
5
|
*/
|
|
6
|
-
export type Extends<
|
|
7
|
-
|
|
6
|
+
export type Extends<T, EXTENDS> = T extends EXTENDS ? true : false;
|
|
8
7
|
/**
|
|
9
8
|
* **IfExtends**
|
|
10
9
|
*
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Equal } from "../combinators/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,76 @@
|
|
|
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<T, IF, ELSE, MAYBE> = IsTrue<T> extends true
|
|
45
|
+
? IF
|
|
46
|
+
: IsTrue<T> extends false
|
|
47
|
+
? ELSE
|
|
48
|
+
: MAYBE;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Type utility which checks for literal `false` value and then switches type
|
|
52
|
+
* to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
|
|
53
|
+
* is the wide type of `boolean`
|
|
54
|
+
*/
|
|
55
|
+
export type IfFalse<T, IF, ELSE, MAYBE> = IsFalse<T> extends true
|
|
56
|
+
? IF
|
|
57
|
+
: IsTrue<T> extends false
|
|
58
|
+
? ELSE
|
|
59
|
+
: MAYBE;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* **IsBooleanLiteral**
|
|
63
|
+
*
|
|
64
|
+
* Type utility which returns true/false if the boolean value is a _boolean literal_ versus
|
|
65
|
+
* just the wider _boolean_ type.
|
|
66
|
+
*/
|
|
67
|
+
export type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* **IfBooleanLiteral**
|
|
71
|
+
*
|
|
72
|
+
* Branch utility which returns `IF` type when `T` is a boolean literal and `ELSE` otherwise
|
|
73
|
+
*/
|
|
74
|
+
export type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T> extends true
|
|
75
|
+
? IF
|
|
76
|
+
: ELSE;
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NarrowlyContains } from "../boolean-logic";
|
|
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;
|
|
@@ -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;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
DefaultOneToOneMapping,
|
|
7
7
|
} from "src/runtime/dictionary/mapTo";
|
|
8
8
|
import { EnumValues } from "../EnumValues";
|
|
9
|
-
import { TypeDefault } from "../
|
|
9
|
+
import { TypeDefault } from "../boolean-logic/TypeDefault";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Expresses relationship between inputs/outputs:
|
package/src/types/index.ts
CHANGED
|
@@ -37,11 +37,12 @@ export * from "./fluent/index";
|
|
|
37
37
|
export * from "./functions/index";
|
|
38
38
|
export * from "./kv/index";
|
|
39
39
|
export * from "./lists/index";
|
|
40
|
+
export * from "./combinators/index";
|
|
40
41
|
export * from "./literal-unions/index";
|
|
41
42
|
export * from "./string-literals/index";
|
|
42
43
|
export * from "./tuples/index";
|
|
43
44
|
export * from "./type-conversion/index";
|
|
44
|
-
export * from "./
|
|
45
|
+
export * from "./boolean-logic/index";
|
|
45
46
|
|
|
46
47
|
// #endregion auto-indexed files
|
|
47
48
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Equal, Expect } from "@type-challenges/utils";
|
|
2
|
+
import { Contains, NarrowlyContains } from "src/types/boolean-logic/array";
|
|
3
|
+
import { describe, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
describe("Contains<T,A>", () => {
|
|
6
|
+
it("happy-path", () => {
|
|
7
|
+
type T1 = [number, 32, 64, "foo"];
|
|
8
|
+
type T2 = [false, true];
|
|
9
|
+
type T3 = [42, 64, 128];
|
|
10
|
+
type T4 = ["foo", "bar"];
|
|
11
|
+
|
|
12
|
+
type cases = [
|
|
13
|
+
// "foo" extends string so true
|
|
14
|
+
Expect<Equal<Contains<string, T1>, true>>,
|
|
15
|
+
// "bar" does NOT extend "foo"
|
|
16
|
+
Expect<Equal<Contains<"bar", T1>, false>>,
|
|
17
|
+
// T4 has literal string but this will match the wide type string
|
|
18
|
+
Expect<Equal<Contains<string, T4>, true>>,
|
|
19
|
+
// T1 has both wide and narrow versions of "number"
|
|
20
|
+
Expect<Equal<Contains<number, T1>, true>>,
|
|
21
|
+
// T3 has narrow versions of "number"
|
|
22
|
+
Expect<Equal<Contains<number, T3>, true>>,
|
|
23
|
+
// boolean literals evaluate to wide type
|
|
24
|
+
Expect<Equal<Contains<boolean, T2>, true>>
|
|
25
|
+
];
|
|
26
|
+
const cases: cases = [true, true, true, true, true, true];
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("NarrowlyContains<T,A>", () => {
|
|
31
|
+
it("happy-path", () => {
|
|
32
|
+
type T1 = [number, 32, 64, "foo"];
|
|
33
|
+
type T2 = [false, true];
|
|
34
|
+
type T3 = [42, 64, 128];
|
|
35
|
+
type T4 = ["foo", "bar"];
|
|
36
|
+
|
|
37
|
+
type cases = [
|
|
38
|
+
// "foo" is not equal to string
|
|
39
|
+
Expect<Equal<NarrowlyContains<string, T1>, false>>,
|
|
40
|
+
// "foo" does equal "foo"
|
|
41
|
+
Expect<Equal<NarrowlyContains<"foo", T1>, true>>,
|
|
42
|
+
// T4 has literal string but this doesn't match with NarrowlyContains
|
|
43
|
+
Expect<Equal<NarrowlyContains<string, T4>, false>>,
|
|
44
|
+
// T1 has both wide and narrow versions of "number" but match is only on wide type
|
|
45
|
+
Expect<Equal<NarrowlyContains<number, T1>, true>>,
|
|
46
|
+
// T3 has matches on narrow number
|
|
47
|
+
Expect<Equal<NarrowlyContains<42, T3>, true>>,
|
|
48
|
+
// T3 identifies a non-match of narrow numbers
|
|
49
|
+
Expect<Equal<NarrowlyContains<442, T3>, false>>,
|
|
50
|
+
// boolean literals evaluate to wide type
|
|
51
|
+
Expect<Equal<NarrowlyContains<boolean, T2>, false>>
|
|
52
|
+
];
|
|
53
|
+
const cases: cases = [true, true, true, true, true, true, true];
|
|
54
|
+
});
|
|
55
|
+
});
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it } from "vitest";
|
|
2
2
|
import { Equal, Expect } from "@type-challenges/utils";
|
|
3
|
-
import { TypeDefault } from "src/types/
|
|
3
|
+
import { TypeDefault } from "src/types/boolean-logic/TypeDefault";
|
|
4
4
|
import { literal } from "src/runtime/literals";
|
|
5
5
|
|
|
6
6
|
describe("TypeDefault<T,D>", () => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Equal, Expect } from "@type-challenges/utils";
|
|
2
|
+
import { Length } from "src/types";
|
|
3
|
+
import { describe, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
describe("Length<T>", () => {
|
|
6
|
+
it("happy-path", () => {
|
|
7
|
+
const a1 = [1, 2, 3] as const;
|
|
8
|
+
const a2 = [1, 2, 3, 4, 5, 6] as const;
|
|
9
|
+
type A1 = typeof a1;
|
|
10
|
+
type A2 = typeof a2;
|
|
11
|
+
|
|
12
|
+
type cases = [
|
|
13
|
+
//
|
|
14
|
+
Expect<Equal<Length<A1>, 3>>,
|
|
15
|
+
Expect<Equal<Length<A2>, 6>>
|
|
16
|
+
];
|
|
17
|
+
const cases: cases = [true, true];
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -2,6 +2,8 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
|
|
3
3
|
import type { Expect, Equal } from "@type-challenges/utils";
|
|
4
4
|
import {
|
|
5
|
+
ifArray,
|
|
6
|
+
ifArrayPartial,
|
|
5
7
|
ifBoolean,
|
|
6
8
|
ifNumber,
|
|
7
9
|
ifString,
|
|
@@ -9,9 +11,10 @@ import {
|
|
|
9
11
|
ifUndefined,
|
|
10
12
|
isTrue,
|
|
11
13
|
} from "src/runtime/type-checks";
|
|
12
|
-
import { EndsWith, StartsWith } from "src/types";
|
|
14
|
+
import { EndsWith, Extends, Or, StartsWith } from "src/types";
|
|
13
15
|
import { ifStartsWith, startsWith } from "src/runtime/type-checks/startsWith";
|
|
14
16
|
import { box } from "src/runtime/literals";
|
|
17
|
+
import { or } from "src/runtime";
|
|
15
18
|
|
|
16
19
|
describe("runtime if/is", () => {
|
|
17
20
|
it("ifString(v,i,e)", () => {
|
|
@@ -55,7 +58,7 @@ describe("runtime if/is", () => {
|
|
|
55
58
|
type cases = [
|
|
56
59
|
Expect<Equal<typeof t, 42>>, //
|
|
57
60
|
Expect<Equal<typeof f, 42>>, //
|
|
58
|
-
Expect<Equal<typeof f2, 42>> //
|
|
61
|
+
Expect<Equal<typeof f2, "yikes" | 42>> //
|
|
59
62
|
];
|
|
60
63
|
const cases: cases = [true, true, true];
|
|
61
64
|
});
|
|
@@ -115,6 +118,104 @@ describe("runtime if/is", () => {
|
|
|
115
118
|
const cases: cases = [true, true];
|
|
116
119
|
});
|
|
117
120
|
|
|
121
|
+
it("Or<T[]> type util", () => {
|
|
122
|
+
type T1 = Or<[true, true, false]>;
|
|
123
|
+
type T2 = Or<[false, false, false]>;
|
|
124
|
+
type T3 = Or<[boolean, boolean, true]>;
|
|
125
|
+
type T4 = Or<[boolean, boolean, boolean]>;
|
|
126
|
+
|
|
127
|
+
type cases = [
|
|
128
|
+
Expect<Equal<T1, true>>,
|
|
129
|
+
Expect<Equal<T2, false>>,
|
|
130
|
+
Expect<Equal<T3, true>>,
|
|
131
|
+
Expect<Equal<T4, boolean>>
|
|
132
|
+
];
|
|
133
|
+
const cases: cases = [true, true, true, true];
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("or() runtime utility", () => {
|
|
137
|
+
const t1 = or(true, true, false);
|
|
138
|
+
const t2 = or(false, false, false);
|
|
139
|
+
const t3 = or(false as boolean, false, true);
|
|
140
|
+
const t4 = or(false as boolean, false as boolean, true as boolean);
|
|
141
|
+
|
|
142
|
+
type cases = [
|
|
143
|
+
Expect<Equal<typeof t1, true>>,
|
|
144
|
+
Expect<Equal<typeof t2, false>>,
|
|
145
|
+
Expect<Equal<typeof t3, true>>,
|
|
146
|
+
Expect<Equal<typeof t4, boolean>>
|
|
147
|
+
];
|
|
148
|
+
const cases: cases = [true, true, true, true];
|
|
149
|
+
|
|
150
|
+
expect(t1).toBe(true);
|
|
151
|
+
expect(t2).toBe(false);
|
|
152
|
+
expect(t3).toBe(true);
|
|
153
|
+
expect(t4).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("Extends<T,EXTENDS> with single clause", () => {
|
|
157
|
+
type cases = [
|
|
158
|
+
//
|
|
159
|
+
Expect<Equal<Extends<1, number>, true>>,
|
|
160
|
+
Expect<Equal<Extends<2, string>, false>>,
|
|
161
|
+
Expect<Equal<Extends<2, 2 | 3>, true>>
|
|
162
|
+
];
|
|
163
|
+
const cases: cases = [true, true, true];
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("IfExtends<T,EXTENDS,IF,ELSE", () => {
|
|
167
|
+
type cases = [/** type tests */];
|
|
168
|
+
const cases: cases = [];
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("ifArray(val,if,else) utility", () => {
|
|
172
|
+
const fn0 = ifArray(
|
|
173
|
+
"foobar" as string,
|
|
174
|
+
(i) => `I'm an array, my length is ${i.length}` as const,
|
|
175
|
+
(i) => `I'm not an array, I am ${i}` as const
|
|
176
|
+
);
|
|
177
|
+
const fn1 = ifArray(
|
|
178
|
+
"foobar",
|
|
179
|
+
(i) => `I'm an array, my length is ${i.length}` as const,
|
|
180
|
+
(i) => `I'm not an array, I am ${i}` as const
|
|
181
|
+
);
|
|
182
|
+
const fn2 = ifArray(
|
|
183
|
+
["foo", "bar"] as const,
|
|
184
|
+
(i) => `I'm an array, my length is ${i.length}` as const,
|
|
185
|
+
(i) => `I'm not an array, I am ${i}` as const
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const fn3 = ifArray(
|
|
189
|
+
["foo", "bar"],
|
|
190
|
+
(i) => `I'm an array, my length is ${i.length}` as const,
|
|
191
|
+
(i) => `I'm not an array, I am ${i}` as const
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
type cases = [
|
|
195
|
+
Expect<Equal<typeof fn0, `I'm not an array, I am ${string}`>>,
|
|
196
|
+
Expect<Equal<typeof fn1, `I'm not an array, I am foobar`>>,
|
|
197
|
+
Expect<Equal<typeof fn2, `I'm an array, my length is 2`>>,
|
|
198
|
+
Expect<Equal<typeof fn3, `I'm an array, my length is ${number}`>>
|
|
199
|
+
];
|
|
200
|
+
const cases: cases = [true, true, true, true];
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("ifArrayPartial()()", () => {
|
|
204
|
+
const arrTest = ifArrayPartial<string | string[]>()(
|
|
205
|
+
(i) => `I'm an array, my length is ${i.length}`,
|
|
206
|
+
(i) => `I'm not an array, I am ${i}`
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const t1 = arrTest("Bob");
|
|
210
|
+
const t2 = arrTest(["foo", "bar"]);
|
|
211
|
+
|
|
212
|
+
type cases = [
|
|
213
|
+
Expect<Equal<typeof t1, `I'm not an array, I am ${string}`>>,
|
|
214
|
+
Expect<Equal<typeof t2, `I'm an array, my length is ${number}`>>
|
|
215
|
+
];
|
|
216
|
+
const cases: cases = [true, true];
|
|
217
|
+
});
|
|
218
|
+
|
|
118
219
|
it("ifUndefined(v,i,e)", () => {
|
|
119
220
|
const t = ifUndefined(undefined, 42, false);
|
|
120
221
|
const f = ifUndefined(false, "yikes", 42);
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* **IsBooleanLiteral**
|
|
3
|
-
*
|
|
4
|
-
* Type utility which returns true/false if the boolean value is a _boolean literal_ versus
|
|
5
|
-
* just the wider _boolean_ type.
|
|
6
|
-
*/
|
|
7
|
-
export type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* **IfBooleanLiteral**
|
|
11
|
-
*
|
|
12
|
-
* Branch utility which returns `IF` type when `T` is a boolean literal and `ELSE` otherwise
|
|
13
|
-
*/
|
|
14
|
-
export type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T> extends true
|
|
15
|
-
? IF
|
|
16
|
-
: ELSE;
|