inferred-types 0.34.0 → 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/dist/index.d.ts CHANGED
@@ -166,6 +166,19 @@ type AfterFirst<T extends readonly any[]> = T extends readonly [any, ...any[]] ?
166
166
  */
167
167
  type FirstString<T> = T extends [infer S extends string, ...unknown[]] ? S : never;
168
168
 
169
+ /**
170
+ * **FilterTuple**
171
+ *
172
+ * Allows a known tuple `T` to be _filtered down_ by eliminating all items
173
+ * in the Tuple that _extend_ type `F`
174
+ * ```ts
175
+ * type T = [1,"foo",3];
176
+ * // [1,3]
177
+ * type T2 = FilterTuple<T, string>;
178
+ * ```
179
+ */
180
+ type FilterTuple<TTuple extends any[] | readonly any[], TFilter, Result extends any[] = []> = TTuple extends [infer A, ...infer R] ? [A] extends [TFilter] ? FilterTuple<R, TFilter, Result> : FilterTuple<R, TFilter, [...Result, A]> : Result;
181
+
169
182
  /**
170
183
  * **Split**`<T, SEP>`
171
184
  *
@@ -280,26 +293,26 @@ type IsFalse<T extends Narrowable> = IsBoolean<T> extends true ? T extends false
280
293
  * to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
281
294
  * is the wide type of `boolean`
282
295
  */
283
- type IfTrue<T, IF, ELSE, MAYBE> = IsTrue<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
296
+ type IfTrue<T extends boolean, IF extends Narrowable, ELSE extends Narrowable, MAYBE extends Narrowable> = IsTrue<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
284
297
  /**
285
298
  * Type utility which checks for literal `false` value and then switches type
286
299
  * to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
287
300
  * is the wide type of `boolean`
288
301
  */
289
- type IfFalse<T, IF, ELSE, MAYBE> = IsFalse<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
302
+ type IfFalse<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable, MAYBE extends Narrowable> = IsFalse<T> extends true ? IF : IsTrue<T> extends false ? ELSE : MAYBE;
290
303
  /**
291
304
  * **IsBooleanLiteral**
292
305
  *
293
306
  * Type utility which returns true/false if the boolean value is a _boolean literal_ versus
294
307
  * just the wider _boolean_ type.
295
308
  */
296
- type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
309
+ type IsBooleanLiteral<T extends Narrowable> = IsTrue<T> extends true ? true : IsFalse<T> extends true ? true : false;
297
310
  /**
298
311
  * **IfBooleanLiteral**
299
312
  *
300
313
  * Branch utility which returns `IF` type when `T` is a boolean literal and `ELSE` otherwise
301
314
  */
302
- type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T> extends true ? IF : ELSE;
315
+ type IfBooleanLiteral<T extends boolean, IF extends Narrowable, ELSE extends Narrowable> = IsBooleanLiteral<T> extends true ? IF : ELSE;
303
316
 
304
317
  /**
305
318
  * **IsStringLiteral**
@@ -307,14 +320,15 @@ type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T> extends
307
320
  * Type utility which returns true/false if the string a _string literal_ versus
308
321
  * just the _string_ type.
309
322
  */
310
- type IsStringLiteral<T> = [T] extends [string] ? (string extends T ? false : true) : false;
323
+ type IsStringLiteral<T extends Narrowable> = [T] extends [string] ? string extends T ? false : true : false;
311
324
  /**
312
325
  * **IfStringLiteral**
313
326
  *
314
327
  * Branch utility which returns `IF` type when `T` is a string literal and `ELSE` otherwise
315
328
  */
316
- type IfStringLiteral<T, IF, ELSE> = [IsStringLiteral<T>] extends [true] ? IF : ELSE;
317
-
329
+ type IfStringLiteral<T extends string, IF extends Narrowable, ELSE extends Narrowable> = [
330
+ IsStringLiteral<T>
331
+ ] extends [true] ? IF : ELSE;
318
332
  /**
319
333
  * **IsNumericLiteral**
320
334
  *
@@ -327,8 +341,7 @@ type IsNumericLiteral<T extends number> = number extends T ? false : true;
327
341
  *
328
342
  * Branch utility which returns `IF` type when `T` is a numeric literal and `ELSE` otherwise
329
343
  */
330
- type IfNumericLiteral<T extends number, IF, ELSE> = IsNumericLiteral<T> extends true ? IF : ELSE;
331
-
344
+ type IfNumericLiteral<T extends number, IF extends Narrowable, ELSE extends Narrowable> = IsNumericLiteral<T> extends true ? IF : ELSE;
332
345
  /**
333
346
  * **IsLiteral**
334
347
  *
@@ -354,17 +367,17 @@ type IsOptionalLiteral<T> = [Exclude<T, undefined>] extends [string] ? IsStringL
354
367
  *
355
368
  * Branch type utility with return `IF` when `T` is a _literal_ value and `ELSE` otherwise
356
369
  */
357
- type IfLiteral<T, IF, ELSE> = IsLiteral<T> extends true ? IF : ELSE;
370
+ type IfLiteral<T, IF extends Narrowable, ELSE extends Narrowable> = IsLiteral<T> extends true ? IF : ELSE;
358
371
  /**
359
372
  * **IfOptionalLiteral**
360
373
  *
361
374
  * Branch type utility with return `IF` when `T` is a _literal_ value (with possibly
362
375
  * the inclusion of _undefined_); otherwise returns the type `ELSE`
363
376
  */
364
- type IfOptionalLiteral<T, IF, ELSE> = IsOptionalLiteral<T> extends true ? IF : ELSE;
377
+ type IfOptionalLiteral<T, IF extends Narrowable, ELSE extends Narrowable> = IsOptionalLiteral<T> extends true ? IF : ELSE;
365
378
 
366
379
  /**
367
- * **Includes<TSource, TValue>**
380
+ * **Includes**`<TSource, TValue>`
368
381
  *
369
382
  * Type utility which returns `true` or `false` based on whether `TValue` is found
370
383
  * in `TSource`. Where `TSource` can be a string literal or an array of string literals.
@@ -373,15 +386,15 @@ type IfOptionalLiteral<T, IF, ELSE> = IsOptionalLiteral<T> extends true ? IF : E
373
386
  * no way to know at design-time whether the value includes `TValue` and so it will return
374
387
  * a type of `boolean`.
375
388
  */
376
- type Includes<TSource extends string | string[], TValue extends string> = TSource extends string[] ? IsStringLiteral<TupleToUnion<TSource>> extends true ? IsLiteral<TValue> extends true ? TValue extends TupleToUnion<TSource> ? true : false : boolean : boolean : TSource extends string ? IsLiteral<TSource> extends true ? IsLiteral<TValue> extends true ? TSource extends `${string}${TValue}${string}` ? true : false : boolean : boolean : boolean;
389
+ type Includes<TSource extends string | readonly string[], TValue extends string> = TSource extends string[] ? IsStringLiteral<TupleToUnion<TSource>> extends true ? IsLiteral<TValue> extends true ? TValue extends TupleToUnion<TSource> ? true : false : boolean : boolean : TSource extends string ? IsLiteral<TSource> extends true ? IsLiteral<TValue> extends true ? TSource extends `${string}${TValue}${string}` ? true : false : boolean : boolean : boolean;
377
390
 
378
- type IsScalar<T> = [T] extends [string] ? true : [T] extends [number] ? true : [T] extends [boolean] ? true : false;
391
+ type IsScalar<T extends Narrowable> = [T] extends [string] ? true : [T] extends [number] ? true : [T] extends [boolean] ? true : false;
379
392
  /**
380
- * **IfScalar**
393
+ * **IfScalar**`<T, IF, ELSE>`
381
394
  *
382
- * Branch type utility which returns `IF` when `T` is a scalar value and `ELSE` otherwise
395
+ * Branch type utility which returns `IF` when `T` is a scalar value (aka, string, number, or boolean) and `ELSE` otherwise
383
396
  */
384
- type IfScalar<T, IF, ELSE> = IsScalar<T> extends true ? IF : ELSE;
397
+ type IfScalar<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable> = IsScalar<T> extends true ? IF : ELSE;
385
398
 
386
399
  /**
387
400
  * **IsUndefined**
@@ -395,21 +408,21 @@ type IsUndefined<T extends Narrowable> = T extends undefined ? true : false;
395
408
  * Type utility which returns `IF` type when `T` is an _undefined_
396
409
  * otherwise returns `ELSE` type.
397
410
  */
398
- type IfUndefined<T, IF, ELSE> = IsUndefined<T> extends true ? IF : ELSE;
411
+ type IfUndefined<T, IF extends Narrowable, ELSE extends Narrowable> = IsUndefined<T> extends true ? IF : ELSE;
399
412
 
400
413
  /**
401
414
  * **Extends**`<T, EXTENDS>`
402
415
  *
403
416
  * Boolean type utility which returns `true` if `T` _extends_ `EXTENDS`.
404
417
  */
405
- type Extends<T, EXTENDS> = T extends EXTENDS ? true : false;
418
+ type Extends<T extends Narrowable, EXTENDS extends Narrowable> = T extends EXTENDS ? true : false;
406
419
  /**
407
420
  * **IfExtends**
408
421
  *
409
422
  * Branching type utility which returns type `IF` when `E` _extends_ `T`; otherwise
410
423
  * it will return the type `ELSE`.
411
424
  */
412
- type IfExtends<E, T, IF, ELSE> = Extends<E, T> extends true ? IF : ELSE;
425
+ type IfExtends<T extends Narrowable, EXTENDS extends Narrowable, IF extends Narrowable, ELSE extends Narrowable> = Extends<T, EXTENDS> extends true ? IF : ELSE;
413
426
 
414
427
  /**
415
428
  * Often when mutating the shape of an object you will end up with the union of a number of
@@ -460,7 +473,7 @@ type IsObject<T> = Mutable<T> extends Record<string, any> ? T extends FunctionTy
460
473
  * Branch type utility with return `IF` when `T` extends an object type
461
474
  * and `ELSE` otherwise
462
475
  */
463
- type IfObject<T, IF, ELSE> = IsObject<T> extends true ? IF : ELSE;
476
+ type IfObject<T, IF extends Narrowable, ELSE extends Narrowable> = IsObject<T> extends true ? IF : ELSE;
464
477
 
465
478
  /**
466
479
  * **StartsWith**<TValue, TStartsWith>
@@ -471,8 +484,7 @@ type IfObject<T, IF, ELSE> = IsObject<T> extends true ? IF : ELSE;
471
484
  * to a literal `true` or `false` but if either is not a literal that it will
472
485
  * just resolve to `boolean` as the value can not be known at design time..
473
486
  */
474
- type StartsWith<TValue extends unknown, TStartsWith extends unknown> = TValue extends string ? TStartsWith extends string ? TValue extends `${TStartsWith}${string}` ? IfStringLiteral<TValue, //
475
- IfStringLiteral<TStartsWith, true, boolean>, boolean> : IfStringLiteral<TValue, false, boolean> : false : false;
487
+ type StartsWith<TValue extends string, TStartsWith extends string> = IsStringLiteral<TStartsWith> extends true ? IsStringLiteral<TValue> extends true ? TValue extends `${TStartsWith}${string}` ? true : false : boolean : boolean;
476
488
  /**
477
489
  * **IfStartsWith**<TValue, TStartsWith, IF, ELSE, MAYBE>
478
490
  *
@@ -483,7 +495,7 @@ IfStringLiteral<TStartsWith, true, boolean>, boolean> : IfStringLiteral<TValue,
483
495
  * which can be stated for cases where TValue or TStartsWith _might_ be the wider `string`
484
496
  * type and therefore the type is unknown at design time.
485
497
  */
486
- type IfStartsWith<TValue extends unknown, TStartsWith extends unknown, IF extends Narrowable, ELSE extends Narrowable> = StartsWith<TValue, TStartsWith> extends true ? IF : StartsWith<TValue, TStartsWith> extends false ? ELSE : IF | ELSE;
498
+ type IfStartsWith<TValue extends string, TStartsWith extends string, IF extends Narrowable, ELSE extends Narrowable> = StartsWith<TValue, TStartsWith> extends true ? IF : StartsWith<TValue, TStartsWith> extends false ? ELSE : IF | ELSE;
487
499
 
488
500
  /**
489
501
  * **EndsWith**<T,U>
@@ -494,8 +506,22 @@ type IfStartsWith<TValue extends unknown, TStartsWith extends unknown, IF extend
494
506
  * to a literal `true` or `false` but if either is not a literal that it will
495
507
  * just resolve to `boolean` as the value can not be known at design time..
496
508
  */
497
- type EndsWith<T extends unknown, U extends unknown> = T extends string ? U extends string ? T extends `${string}${U}` ? IfStringLiteral<T, //
498
- IfStringLiteral<U, true, boolean>, boolean> : IfStringLiteral<T, false, boolean> : false : false;
509
+ type EndsWith<TValue extends string, TEndsWith extends string> = IsStringLiteral<TEndsWith> extends true ? IsStringLiteral<TValue> extends true ? TValue extends `${string}${TEndsWith}` ? true : false : boolean : boolean;
510
+ /**
511
+ * **IfEndsWith**<TValue, TEndsWith, IF, ELSE, MAYBE>
512
+ *
513
+ * Type utility which converts type to `IF` type _if_ `TValue` _ends with_ `TEndsWith` but
514
+ * otherwise converts type to `ELSE`. If there are wide types in the mix then the type will
515
+ * result in the union of IF and ELSE.
516
+ */
517
+ type IfEndsWith<TValue extends string, TEndsWith extends string, IF extends Narrowable, ELSE extends Narrowable> = EndsWith<TValue, TEndsWith> extends true ? IF : EndsWith<TValue, TEndsWith> extends false ? ELSE : IF | ELSE;
518
+
519
+ /**
520
+ * **Or**`<T>`
521
+ *
522
+ * Takes an array of boolean values and produces a boolean OR across these values
523
+ */
524
+ type Or<T extends readonly boolean[]> = NarrowlyContains<true, T> extends true ? true : NarrowlyContains<boolean, T> extends true ? boolean : false;
499
525
 
500
526
  /**
501
527
  * Makes a readonly structure mutable
@@ -1698,13 +1724,6 @@ type KvFrom<T extends object> = Array<{
1698
1724
  */
1699
1725
  type KvTuple<T, K extends keyof T> = [K, Record<K, T[K]>];
1700
1726
 
1701
- /**
1702
- * **Or**`<T>`
1703
- *
1704
- * Takes an array of boolean values and produces a boolean OR across these values
1705
- */
1706
- type Or<T extends readonly boolean[]> = NarrowlyContains<true, T> extends true ? true : NarrowlyContains<boolean, T> extends true ? boolean : false;
1707
-
1708
1727
  type DictArrayFilterCallback<K extends keyof T, T extends object, R extends true | false> = (key: K, value: Pick<T, K>) => R;
1709
1728
  /**
1710
1729
  * An element in a `DictArray` shaped as a two element tuple: `[key, kv]`.
@@ -2280,7 +2299,7 @@ declare function isFalse<T>(i: T): IsFalse<T>;
2280
2299
  * typed so unlike the type utility there is no "MAYBE" state but if a wide type if
2281
2300
  * encountered the _type_ will the union of `IF` and `ELSE`.
2282
2301
  */
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>;
2302
+ declare function ifFalse<T extends boolean, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IfFalse<T, IF, ELSE, IF | ELSE>;
2284
2303
 
2285
2304
  type IsFunction<T> = T extends FunctionType ? true : false;
2286
2305
  type HybridFunction<TProps extends {}> = (<TArgs extends any[]>(...args: TArgs) => any) & TProps;
@@ -2353,7 +2372,7 @@ type IsString<T> = T extends string ? true : false;
2353
2372
  * returns `IF` type if it is, otherwise returns the type `ELSE`.
2354
2373
  */
2355
2374
  type IfString<T extends Narrowable, //
2356
- IF extends Narrowable, ELSE extends Narrowable> = IsString<T> extends true ? IF : ELSE;
2375
+ IF extends Narrowable, ELSE extends Narrowable> = IsString<T> extends true ? IF : IsString<T> extends false ? ELSE : IF | ELSE;
2357
2376
 
2358
2377
  /**
2359
2378
  * **isString**
@@ -2388,8 +2407,7 @@ declare function isTrue<T extends Narrowable>(i: T): IsTrue<T>;
2388
2407
  * **ifTrue**
2389
2408
  *
2390
2409
  * Strongly type-aware conditional statement which checks whether a value is
2391
- * a _true_ and returns one of two values (strongly typed) based on the evaluation
2392
- * of this criteria.
2410
+ * _true_.
2393
2411
  *
2394
2412
  * @param val the value being tested
2395
2413
  * @param ifVal the value (strongly typed) returned if val is _true_ value
@@ -2399,7 +2417,7 @@ declare function isTrue<T extends Narrowable>(i: T): IsTrue<T>;
2399
2417
  * typed so unlike the type utility there is no "MAYBE" state but if a wide type if
2400
2418
  * encountered the _type_ will the union of `IF` and `ELSE`.
2401
2419
  */
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>;
2420
+ declare function ifTrue<T extends boolean, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IfTrue<T, IF, ELSE, IF | ELSE>;
2403
2421
 
2404
2422
  declare function isUndefined<T extends Narrowable>(i: T): undefined extends T ? true : false;
2405
2423
  /**
@@ -2523,4 +2541,4 @@ interface IFluentConfigurator<C> {
2523
2541
  */
2524
2542
  declare function FluentConfigurator<I>(initial?: I): IFluentConfigurator<{}>;
2525
2543
 
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 };
2544
+ 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, FilterTuple, FinalReturn, FinalizedMapConfig, First, FirstKey, FirstKeyValue, FirstOfEach, FirstOrUndefined, FirstString, FluentConfigurator, FluentFunction, FnShape, FromDictArray, FullyQualifiedUrl, FunctionType, GeneralDictionary, Get, HasUppercase, HybridFunction, IConfigurator, IFluentConfigurator, If, IfArray, IfBooleanLiteral, IfEndsWith, 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inferred-types",
3
- "version": "0.34.0",
3
+ "version": "0.34.2",
4
4
  "description": "Functions which provide useful type inference on TS projects",
5
5
  "license": "MIT",
6
6
  "author": "Ken Snyder<ken@ken.net>",
@@ -1,4 +1,4 @@
1
- import { Or } from "src/types/combinators/Or";
1
+ import { Or } from "src/types/boolean-logic/Or";
2
2
 
3
3
  export function or<O extends readonly boolean[]>(...conditions: O) {
4
4
  return (conditions.some((v) => v === true) ? true : false) as Or<O>;
@@ -20,7 +20,7 @@ export function isFalse<T>(i: T) {
20
20
  * typed so unlike the type utility there is no "MAYBE" state but if a wide type if
21
21
  * encountered the _type_ will the union of `IF` and `ELSE`.
22
22
  */
23
- export function ifFalse<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(
23
+ export function ifFalse<T extends boolean, IF extends Narrowable, ELSE extends Narrowable>(
24
24
  val: T,
25
25
  ifVal: IF,
26
26
  elseVal: ELSE
@@ -12,8 +12,7 @@ export function isTrue<T extends Narrowable>(i: T) {
12
12
  * **ifTrue**
13
13
  *
14
14
  * Strongly type-aware conditional statement which checks whether a value is
15
- * a _true_ and returns one of two values (strongly typed) based on the evaluation
16
- * of this criteria.
15
+ * _true_.
17
16
  *
18
17
  * @param val the value being tested
19
18
  * @param ifVal the value (strongly typed) returned if val is _true_ value
@@ -23,7 +22,7 @@ export function isTrue<T extends Narrowable>(i: T) {
23
22
  * typed so unlike the type utility there is no "MAYBE" state but if a wide type if
24
23
  * encountered the _type_ will the union of `IF` and `ELSE`.
25
24
  */
26
- export function ifTrue<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(
25
+ export function ifTrue<T extends boolean, IF extends Narrowable, ELSE extends Narrowable>(
27
26
  val: T,
28
27
  ifVal: IF,
29
28
  elseVal: ELSE
@@ -1,3 +1,4 @@
1
+ import { Narrowable } from "src/types";
1
2
  import { IfStartsWith, StartsWith } from "src/types/boolean-logic";
2
3
  import { IfUndefined } from "src/types/boolean-logic/IsUndefined";
3
4
  import { createFnWithProps } from "../createFnWithProps";
@@ -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
- <I extends string>(input: I) =>
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
- ) as IfStartsWith<I, TStartsWith, ReturnType<TIf>, ReturnType<TElse>>;
107
+ );
@@ -1,4 +1,5 @@
1
- import { IfStringLiteral } from "src/types/boolean-logic";
1
+ import { IsStringLiteral } from "src/types/boolean-logic";
2
+ import { Narrowable } from "../Narrowable";
2
3
 
3
4
  /**
4
5
  * **EndsWith**<T,U>
@@ -9,14 +10,31 @@ import { IfStringLiteral } from "src/types/boolean-logic";
9
10
  * to a literal `true` or `false` but if either is not a literal that it will
10
11
  * just resolve to `boolean` as the value can not be known at design time..
11
12
  */
12
- export type EndsWith<T extends unknown, U extends unknown> = T extends string
13
- ? U extends string
14
- ? T extends `${string}${U}`
15
- ? IfStringLiteral<
16
- T, //
17
- IfStringLiteral<U, true, boolean>,
18
- boolean
19
- >
20
- : IfStringLiteral<T, false, boolean>
21
- : false
22
- : false;
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;
@@ -1,13 +1,22 @@
1
+ import { Narrowable } from "../Narrowable";
2
+
1
3
  /**
2
4
  * **Extends**`<T, EXTENDS>`
3
5
  *
4
6
  * Boolean type utility which returns `true` if `T` _extends_ `EXTENDS`.
5
7
  */
6
- export type Extends<T, EXTENDS> = T extends EXTENDS ? true : false;
8
+ export type Extends<T extends Narrowable, EXTENDS extends Narrowable> = T extends EXTENDS
9
+ ? true
10
+ : false;
7
11
  /**
8
12
  * **IfExtends**
9
13
  *
10
14
  * Branching type utility which returns type `IF` when `E` _extends_ `T`; otherwise
11
15
  * it will return the type `ELSE`.
12
16
  */
13
- export type IfExtends<E, T, IF, ELSE> = Extends<E, T> extends true ? IF : ELSE;
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<TSource, TValue>**
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 { Narrowable } from "../Narrowable";
1
2
  import { IsBooleanLiteral } from "./boolean";
2
- import { IsStringLiteral } from "./IsStringLiteral";
3
- import { IsNumericLiteral } from "./IsNumericLiteral";
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 ? IF : ELSE;
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<T, IF, ELSE> = IsOptionalLiteral<T> extends true ? IF : ELSE;
97
+ export type IfOptionalLiteral<
98
+ T,
99
+ IF extends Narrowable,
100
+ ELSE extends Narrowable
101
+ > = IsOptionalLiteral<T> extends true ? IF : ELSE;
@@ -1,4 +1,6 @@
1
- export type IsScalar<T> = [T] extends [string]
1
+ import { Narrowable } from "../Narrowable";
2
+
3
+ export type IsScalar<T extends Narrowable> = [T] extends [string]
2
4
  ? true
3
5
  : [T] extends [number]
4
6
  ? true
@@ -7,8 +9,12 @@ export type IsScalar<T> = [T] extends [string]
7
9
  : false;
8
10
 
9
11
  /**
10
- * **IfScalar**
12
+ * **IfScalar**`<T, IF, ELSE>`
11
13
  *
12
- * Branch type utility which returns `IF` when `T` is a scalar value and `ELSE` otherwise
14
+ * Branch type utility which returns `IF` when `T` is a scalar value (aka, string, number, or boolean) and `ELSE` otherwise
13
15
  */
14
- export type IfScalar<T, IF, ELSE> = IsScalar<T> extends true ? IF : ELSE;
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<T, IF, ELSE> = IsUndefined<T> extends true ? IF : ELSE;
16
+ export type IfUndefined<
17
+ T,
18
+ IF extends Narrowable,
19
+ ELSE extends Narrowable
20
+ > = IsUndefined<T> extends true ? IF : ELSE;
@@ -1,4 +1,4 @@
1
- import { NarrowlyContains } from "../boolean-logic";
1
+ import { NarrowlyContains } from "./array";
2
2
 
3
3
  /**
4
4
  * **Or**`<T>`
@@ -1,4 +1,4 @@
1
- import { IfStringLiteral } from "src/types/boolean-logic";
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<TValue extends unknown, TStartsWith extends unknown> = TValue extends string
13
- ? TStartsWith extends string
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
- ? IfStringLiteral<
16
- TValue, //
17
- IfStringLiteral<TStartsWith, true, boolean>,
18
- boolean
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 unknown,
36
- TStartsWith extends unknown,
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
@@ -1,4 +1,4 @@
1
- import { Equal } from "../combinators/equivalency";
1
+ import { Equal } from "./equivalency";
2
2
  import { AfterFirst, First } from "../lists";
3
3
  import { Narrowable } from "../Narrowable";
4
4
 
@@ -41,22 +41,24 @@ export type IsFalse<T extends Narrowable> = IsBoolean<T> extends true
41
41
  * to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
42
42
  * is the wide type of `boolean`
43
43
  */
44
- export type IfTrue<T, IF, ELSE, MAYBE> = IsTrue<T> extends true
45
- ? IF
46
- : IsTrue<T> extends false
47
- ? ELSE
48
- : MAYBE;
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;
49
50
 
50
51
  /**
51
52
  * Type utility which checks for literal `false` value and then switches type
52
53
  * to the IF, ELSE, or MAYBE generic types passed in where _maybe_ is when T
53
54
  * is the wide type of `boolean`
54
55
  */
55
- export type IfFalse<T, IF, ELSE, MAYBE> = IsFalse<T> extends true
56
- ? IF
57
- : IsTrue<T> extends false
58
- ? ELSE
59
- : MAYBE;
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;
60
62
 
61
63
  /**
62
64
  * **IsBooleanLiteral**
@@ -64,13 +66,19 @@ export type IfFalse<T, IF, ELSE, MAYBE> = IsFalse<T> extends true
64
66
  * Type utility which returns true/false if the boolean value is a _boolean literal_ versus
65
67
  * just the wider _boolean_ type.
66
68
  */
67
- export type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
69
+ export type IsBooleanLiteral<T extends Narrowable> = IsTrue<T> extends true
70
+ ? true
71
+ : IsFalse<T> extends true
72
+ ? true
73
+ : false;
68
74
 
69
75
  /**
70
76
  * **IfBooleanLiteral**
71
77
  *
72
78
  * Branch utility which returns `IF` type when `T` is a boolean literal and `ELSE` otherwise
73
79
  */
74
- export type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T> extends true
75
- ? IF
76
- : ELSE;
80
+ export type IfBooleanLiteral<
81
+ T extends boolean,
82
+ IF extends Narrowable,
83
+ ELSE extends Narrowable
84
+ > = IsBooleanLiteral<T> extends true ? IF : ELSE;
@@ -1,9 +1,7 @@
1
1
  export * from "./array";
2
2
  export * from "./Includes";
3
3
  export * from "./boolean";
4
- export * from "./IsNumericLiteral";
5
4
  export * from "./IsScalar";
6
- export * from "./IsStringLiteral";
7
5
  export * from "./IsLiteral";
8
6
  export * from "./IsUndefined";
9
7
  export * from "./Extends";
@@ -11,3 +9,5 @@ export * from "./TypeDefault";
11
9
  export * from "./object";
12
10
  export * from "./StartsWith";
13
11
  export * from "./EndsWith";
12
+ export * from "./Or";
13
+ export * from "./equivalency";
@@ -1,5 +1,6 @@
1
1
  import { FunctionType } from "../FunctionType";
2
2
  import { Mutable } from "../Mutable";
3
+ import { Narrowable } from "../Narrowable";
3
4
 
4
5
  /**
5
6
  * **IsObject**
@@ -24,4 +25,6 @@ export type IsObject<T> = Mutable<T> extends Record<string, any>
24
25
  * Branch type utility with return `IF` when `T` extends an object type
25
26
  * and `ELSE` otherwise
26
27
  */
27
- export type IfObject<T, IF, ELSE> = IsObject<T> extends true ? IF : ELSE;
28
+ export type IfObject<T, IF extends Narrowable, ELSE extends Narrowable> = IsObject<T> extends true
29
+ ? IF
30
+ : ELSE;
@@ -18,4 +18,4 @@ export type IfString<
18
18
  T extends Narrowable, //
19
19
  IF extends Narrowable,
20
20
  ELSE extends Narrowable
21
- > = IsString<T> extends true ? IF : ELSE;
21
+ > = IsString<T> extends true ? IF : IsString<T> extends false ? ELSE : IF | ELSE;
@@ -37,7 +37,6 @@ 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";
41
40
  export * from "./literal-unions/index";
42
41
  export * from "./string-literals/index";
43
42
  export * from "./tuples/index";
@@ -0,0 +1,20 @@
1
+ /**
2
+ * **FilterTuple**
3
+ *
4
+ * Allows a known tuple `T` to be _filtered down_ by eliminating all items
5
+ * in the Tuple that _extend_ type `F`
6
+ * ```ts
7
+ * type T = [1,"foo",3];
8
+ * // [1,3]
9
+ * type T2 = FilterTuple<T, string>;
10
+ * ```
11
+ */
12
+ export type FilterTuple<
13
+ TTuple extends any[] | readonly any[],
14
+ TFilter,
15
+ Result extends any[] = []
16
+ > = TTuple extends [infer A, ...infer R]
17
+ ? [A] extends [TFilter]
18
+ ? FilterTuple<R, TFilter, Result>
19
+ : FilterTuple<R, TFilter, [...Result, A]>
20
+ : Result;
@@ -8,6 +8,7 @@
8
8
  export * from "./AfterFirst";
9
9
  export * from "./First";
10
10
  export * from "./FirstString";
11
+ export * from "./FilterTuple";
11
12
  export * from "./Split";
12
13
  export * from "./UniqueForProp";
13
14
 
@@ -11,7 +11,7 @@ import {
11
11
  ifUndefined,
12
12
  isTrue,
13
13
  } from "src/runtime/type-checks";
14
- import { EndsWith, Extends, Or, StartsWith } from "src/types";
14
+ import { EndsWith, Extends, LowerAlpha, Or, StartsWith } from "src/types";
15
15
  import { ifStartsWith, startsWith } from "src/runtime/type-checks/startsWith";
16
16
  import { box } from "src/runtime/literals";
17
17
  import { or } from "src/runtime";
@@ -236,14 +236,21 @@ describe("runtime if/is", () => {
236
236
  type T4 = StartsWith<string, "foo">;
237
237
  type T5 = StartsWith<string, string>;
238
238
 
239
+ type T6 = StartsWith<"alpha", LowerAlpha>;
240
+ type T7 = StartsWith<"Alpha", LowerAlpha>;
241
+
239
242
  type cases = [
240
243
  Expect<Equal<T1, true>>, //
241
244
  Expect<Equal<T2, false>>,
245
+ // if either the "start with" or "val" props are wide then we can't resolve at design time
242
246
  Expect<Equal<T3, boolean>>,
243
247
  Expect<Equal<T4, boolean>>,
244
- Expect<Equal<T5, boolean>>
248
+ Expect<Equal<T5, boolean>>,
249
+ // LowerAlpha is a string literal
250
+ Expect<Equal<T6, true>>,
251
+ Expect<Equal<T7, false>>
245
252
  ];
246
- const cases: cases = [true, true, true, true, true];
253
+ const cases: cases = [true, true, true, true, true, true, true];
247
254
  });
248
255
 
249
256
  it("EndsWith<T,U>", () => {
@@ -288,7 +295,7 @@ describe("runtime if/is", () => {
288
295
  // condition
289
296
  "foo",
290
297
  // inline
291
- (i) => `welcome ${i}` as const,
298
+ (i) => `welcome ${i}`,
292
299
  // external
293
300
  noSir
294
301
  );
@@ -1,16 +0,0 @@
1
- /**
2
- * **IsNumericLiteral**
3
- *
4
- * Type utility which returns true/false if the numeric value a _numeric literal_ versus
5
- * just the _number_ type.
6
- */
7
- export type IsNumericLiteral<T extends number> = number extends T ? false : true;
8
-
9
- /**
10
- * **IfNumericLiteral**
11
- *
12
- * Branch utility which returns `IF` type when `T` is a numeric literal and `ELSE` otherwise
13
- */
14
- export type IfNumericLiteral<T extends number, IF, ELSE> = IsNumericLiteral<T> extends true
15
- ? IF
16
- : ELSE;
@@ -1,14 +0,0 @@
1
- /**
2
- * **IsStringLiteral**
3
- *
4
- * Type utility which returns true/false if the string a _string literal_ versus
5
- * just the _string_ type.
6
- */
7
- export type IsStringLiteral<T> = [T] extends [string] ? (string extends T ? false : true) : false;
8
-
9
- /**
10
- * **IfStringLiteral**
11
- *
12
- * Branch utility which returns `IF` type when `T` is a string literal and `ELSE` otherwise
13
- */
14
- export type IfStringLiteral<T, IF, ELSE> = [IsStringLiteral<T>] extends [true] ? IF : ELSE;
@@ -1,2 +0,0 @@
1
- export * from "./equivalency";
2
- export * from "./Or";