diff --git a/lib/global.d.ts b/lib/global.d.ts index f7bc071..6f1e11c 100644 --- a/lib/global.d.ts +++ b/lib/global.d.ts @@ -1,4 +1,5 @@ -import { AnyObject } from './modules/infrastructure'; +import { ForceExtract } from './modules/app'; +import { AnyObject, DefaultOnUnknown } from './modules/infrastructure'; import { IValidations, TestsCallback } from './readable-test-types'; declare global { @@ -6,10 +7,15 @@ declare global { function testType(description: string, tests: AnyObject | TestsCallback): void; function assertType(): IValidations; + interface INTERNAL_RT_CONFIG { + development: DefaultOnUnknown, false>; + conditionWay: DefaultOnUnknown, 'natural'>; + } + interface RT_CONFIG {} type RT_CONFIG_SCHEME = T; } \ No newline at end of file diff --git a/lib/modules/arrays-and-tuples/infrastructure.d.ts b/lib/modules/arrays-and-tuples/infrastructure.d.ts index 8457ac3..a5a6f61 100644 --- a/lib/modules/arrays-and-tuples/infrastructure.d.ts +++ b/lib/modules/arrays-and-tuples/infrastructure.d.ts @@ -44,7 +44,10 @@ export type IsEmptyArray = T extends [] ? true : false; * type C = IsTuple; * // ^? false */ -export type IsTuple = If, IsAny]>, false, T extends [infer _A, ...(infer _B)] ? true : false> ; +export type IsTuple = If, IsAny]>, { + then: false; + else: T extends [infer _A, ...(infer _B)] ? true : false; +}>; /** * Checks if a tuple `T` includes a specific type `TypeToSearch`. diff --git a/lib/modules/booleans/infrastructure.d.ts b/lib/modules/booleans/infrastructure.d.ts index 1344c2f..d034d1b 100644 --- a/lib/modules/booleans/infrastructure.d.ts +++ b/lib/modules/booleans/infrastructure.d.ts @@ -62,7 +62,10 @@ export type Or> = Not = T extends [infer X, ...infer newT] - ? If, trueFinded]>, false, XOR, Or<[Cast, trueFinded]>>> + ? If, trueFinded]>, { + then: false; + else: XOR, Or<[Cast, trueFinded]>>; + }> : trueFinded; /** @@ -90,7 +93,10 @@ export type Not = T extends true ? false : true; * type D = NotIf; * // ^? false */ -export type NotIf = If, T>; +export type NotIf = If; + else: T; +}>; /* - diff --git a/lib/modules/conditions/app.d.ts b/lib/modules/conditions/app.d.ts index 4b19297..132cae7 100644 --- a/lib/modules/conditions/app.d.ts +++ b/lib/modules/conditions/app.d.ts @@ -1,18 +1,36 @@ +import { ForceExtract } from '../app'; -export type ConditionObject = { +type Explicit = { condition: boolean; - type: unknown; + then: unknown; else: unknown; }; -export type ConditionCaseMap = { - 'true': 'type'; - 'false': 'else'; - 'boolean': 'type' | 'else'; +type Natural = { + then: unknown; + else: unknown; }; -// TODO improve inference of types for generics -export type IfObject = Condition[ConditionCaseMap[`${Condition['condition']}`]]; +export type ExplicitCondition = [ForceExtract] extends [false] ? ForceExtract : ForceExtract; + +export type NaturalCondition = [Condition] extends [false] ? ForceExtract : ForceExtract; + +export type SingleLineCondition = [Condition] extends [false] ? F : T; -export type IfSingleLine = [Condition] extends [true] ? T : F; +export type ExtendsCaseMapA = { + 'singleLine': boolean; + 'natural': boolean; + 'explicit': Explicit; +}; + +export type ExtendsCaseMapB = { + 'singleLine': unknown; + 'natural': Natural; + 'explicit': never; +}; +export type ExtendsCaseMapC = { + 'singleLine': unknown; + 'natural': never; + 'explicit': never; +}; \ No newline at end of file diff --git a/lib/modules/conditions/infrastructure.d.ts b/lib/modules/conditions/infrastructure.d.ts index 305ef4a..1784010 100644 --- a/lib/modules/conditions/infrastructure.d.ts +++ b/lib/modules/conditions/infrastructure.d.ts @@ -1,4 +1,7 @@ -import { ConditionCaseMap, ConditionObject } from './app'; +import { ForceExtract } from '../app'; +import { ExplicitCondition, ExtendsCaseMapA, ExtendsCaseMapB, ExtendsCaseMapC, NaturalCondition, SingleLineCondition } from './app'; + +type IfMode = ForceExtract; /* ! WARNING: This utility has an internal implementation. @@ -17,9 +20,11 @@ import { ConditionCaseMap, ConditionObject } from './app'; * // ^ Type C = string | number */ export type If< - Condition extends boolean | ConditionObject, - TrueCase = never, - FalseCase = never -> = Condition extends ConditionObject - ? Condition[ConditionCaseMap[`${Condition['condition']}`]] - : Condition extends true ? TrueCase : FalseCase; \ No newline at end of file + A extends ExtendsCaseMapA[IfMode], + B extends ExtendsCaseMapB[IfMode] = never, + C extends ExtendsCaseMapC[IfMode] = never +> = { + 'singleLine': SingleLineCondition; + 'natural': NaturalCondition; + 'explicit': ExplicitCondition; +}[IfMode]; \ No newline at end of file diff --git a/lib/modules/conditions/infrastructure.spec-types.ts b/lib/modules/conditions/infrastructure.spec-types.ts index 012726f..7be648e 100644 --- a/lib/modules/conditions/infrastructure.spec-types.ts +++ b/lib/modules/conditions/infrastructure.spec-types.ts @@ -1,27 +1,33 @@ -import { If } from './infrastructure'; +import { ExplicitCondition, NaturalCondition, SingleLineCondition } from './app'; describeType('If', () => { testType('Should return TrueCase if Condition is true', [ - assertType>().equals(), - assertType>().equals<'1234'>(), - assertType>().toBeAny(), + assertType>().equals(), + assertType>().equals<'1234'>(), + assertType>().toBeAny(), ]); testType('Should return FalseCase if Condition is false', [ - assertType>().equals(), - assertType>().equals<1234>(), - assertType>().toBeUnknow(), + assertType>().equals(), + assertType>().equals<1234>(), + assertType>().toBeUnknow(), ]); - testType('Should return TrueCase | FalseCase if Condition is boolean', [ - assertType>().equals(), - assertType>().equals<'1234' | 1234>(), - assertType>().toBeAny(), // in this case any | unknown resolve it as any + testType('Should return TrueCase if Condition is boolean', [ + assertType>().equals(), + assertType>().equals<'1234'>(), + assertType>().toBeAny(), ]); - testType('Should use condition object (variant 1)', [ - assertType>().equals(), - assertType>().equals(), - assertType>().equals(), + testType('Should use condition object', [ + assertType>().equals(), + assertType>().equals(), + assertType>().equals(), + ]); + + testType('Should use Natural condition object', [ + assertType>().equals(), + assertType>().equals(), + assertType>().equals(), ]); }); \ No newline at end of file diff --git a/lib/modules/numbers/math/app/addition.d.ts b/lib/modules/numbers/math/app/addition.d.ts index 908bf0d..1220aa8 100644 --- a/lib/modules/numbers/math/app/addition.d.ts +++ b/lib/modules/numbers/math/app/addition.d.ts @@ -14,7 +14,10 @@ type GetSumCarry = B extends ForceExtract ? 1 : 0; type sumDecimal = { result: GetSum, CarryIn>; - carryOut: If, Equals]>, 1, GetSumCarry, B>>; + carryOut: If, Equals]>, { + then: 1; + else: GetSumCarry, B>; + }>; }; type _next< diff --git a/lib/modules/numbers/math/app/sustraction.d.ts b/lib/modules/numbers/math/app/sustraction.d.ts index 6dd39e4..2fffdc9 100644 --- a/lib/modules/numbers/math/app/sustraction.d.ts +++ b/lib/modules/numbers/math/app/sustraction.d.ts @@ -17,7 +17,10 @@ type getSustractCarry = B extends ForceExtract, B>> = { result: Result; - carryOut: If, Equals]>, 1, getSustractCarry>; + carryOut: If, Equals]>, { + then: 1; + else: getSustractCarry; + }>; }; type _SubstractOnShifted = sustractDecimal>, ToDecimal>, CarryIn>; diff --git a/lib/modules/objects/infrastructure.d.ts b/lib/modules/objects/infrastructure.d.ts index db65704..cbd858d 100644 --- a/lib/modules/objects/infrastructure.d.ts +++ b/lib/modules/objects/infrastructure.d.ts @@ -9,7 +9,7 @@ import { IsUnknown } from '../unknow/infrastructure'; import { AnyFunction } from '../functions/infrastructure'; import { KeysOfUnion } from '../generals/infrastructure'; import { NonUndefined } from '../undefined/infrastructure'; -import { IfSingleLine } from '../conditions/app'; +import { SingleLineCondition } from '../conditions/app'; export * from './app/ModifyPlusOrderedCombinations'; export * from './app/ModifyPlusCombinations'; @@ -47,9 +47,8 @@ export type Modify = IsStrictObject extends true * Allow modify interfaces or object types without the restrictions of use `extends` or `&` operator * Creates a Union Discrimated Type with the overrides + the keys pased for modify the object. */ -export type ModifyByKey = If<{ - condition: And<[IsStrictObject, IsStrictObject]>; - type: Prettify<{ [_ in KeyToDiscrimitate]?: undefined } & T | { [Key in keyof U]: { [_ in KeyToDiscrimitate]: Key } & Modify }[keyof U]>; +export type ModifyByKey = If, IsStrictObject]>, { + then: Prettify<{ [_ in KeyToDiscrimitate]?: undefined } & T | { [Key in keyof U]: { [_ in KeyToDiscrimitate]: Key } & Modify }[keyof U]>; else: T; }>; @@ -82,7 +81,7 @@ export type PickByValue< ? Prettify<_result> : ValuesToPick extends [infer X, ...infer Rest] ? PickByValue, Key>]: Type[Key] + [Key in keyof Type as SingleLineCondition, Key>]: Type[Key] }> : never; @@ -103,10 +102,10 @@ export type CanBeEmptyObject = {} extends Type ? true : false; * // ^? "b" */ export type ReadonlyKeys = { - [Key in keyof Type]-?: If, Key> + [Key in keyof Type]-?: If, { + then: Key; + else: never; + }> }[keyof Type]; /** @@ -116,10 +115,10 @@ export type ReadonlyKeys = { * // ^? "a" */ export type NoReadonlyKeys = { - [Key in keyof Type]-?: If, Key> + [Key in keyof Type]-?: If, { + then: Key; + else: never; + }> }[keyof Type]; /** @@ -129,7 +128,10 @@ export type NoReadonlyKeys = { * // ^? "b" | "c" */ export type RequiredKeys = { - [Key in keyof Type]-?: If>, Key> + [Key in keyof Type]-?: If>, { + then: Key; + else: never; + }> }[keyof Type]; /** @@ -139,7 +141,10 @@ export type RequiredKeys = { * // ^? "a" | "b" */ export type OptionalKeys = { - [Key in keyof Type]-?: If, Key> + [Key in keyof Type]-?: If, { + then: Key; + else: never; + }> }[keyof Type]; /** diff --git a/lib/modules/promises/infrastructure.d.ts b/lib/modules/promises/infrastructure.d.ts index 83982c0..4da748d 100644 --- a/lib/modules/promises/infrastructure.d.ts +++ b/lib/modules/promises/infrastructure.d.ts @@ -13,4 +13,7 @@ import { IsNever } from '../never/infrastructure'; * type C = IsPromise; * // ^? false */ -export type IsPromise = If, false, T extends Promise ? true : false>; \ No newline at end of file +export type IsPromise = If, { + then: false; + else: T extends Promise ? true : false; +}>; \ No newline at end of file diff --git a/lib/modules/unknow/infrastructure.d.ts b/lib/modules/unknow/infrastructure.d.ts index 2580947..dbb19ab 100644 --- a/lib/modules/unknow/infrastructure.d.ts +++ b/lib/modules/unknow/infrastructure.d.ts @@ -16,3 +16,11 @@ import { IsAny } from '../any/infrastructure'; If you are modifying this method, ensure to also update its corresponding internal implementation. */ export type IsUnknown = IsAny extends true ? false : unknown extends Type ? true : false; + +/** + * A utility type that substitutes a default type when the provided type is unknown. + * @example + * type A = DefaultOnUnknown; // Result: string + * type B = DefaultOnUnknown; // Result: number + */ +export type DefaultOnUnknown = IsUnknown extends true ? Default : Type; \ No newline at end of file diff --git a/lib/modules/unknow/infrastructure.spec-types.ts b/lib/modules/unknow/infrastructure.spec-types.ts index 220fedb..8bee54d 100644 --- a/lib/modules/unknow/infrastructure.spec-types.ts +++ b/lib/modules/unknow/infrastructure.spec-types.ts @@ -1,4 +1,4 @@ -import { IsUnknown } from './infrastructure'; +import { DefaultOnUnknown, IsUnknown } from './infrastructure'; describeType('IsUnknown', () => { testType('Should return true only for type unknown', [ @@ -15,4 +15,16 @@ describeType('IsUnknown', () => { assertType>().equals(), assertType>().equals(), ]); + + describeType('DefaultOnUnknown', () => { + testType('Should replace unknown type with the default type', () => { + type result = DefaultOnUnknown; + assertType().equals(); + }); + + testType('Should retain the original type if it is known', () => { + type result = DefaultOnUnknown; + assertType().equals(); + }); + }); }); \ No newline at end of file diff --git a/lib/readable-test-types/index.d.ts b/lib/readable-test-types/index.d.ts index d138f36..8d94dc6 100644 --- a/lib/readable-test-types/index.d.ts +++ b/lib/readable-test-types/index.d.ts @@ -41,7 +41,10 @@ type propertyCallableOnPass< Result extends boolean, Invert extends boolean, keyToErrorsMsg extends keyof FailMsgs -> = If, () => void, FAIL[keyToErrorsMsg]>>; +> = If, { + then: () => void; + else: FAIL[keyToErrorsMsg]>; +}>; interface IValidationsPublic { not: IValidationsPublic>; diff --git a/lib/rt.config.d.ts b/lib/rt.config.d.ts index 472710f..6463a11 100644 --- a/lib/rt.config.d.ts +++ b/lib/rt.config.d.ts @@ -1,4 +1,3 @@ declare interface RT_CONFIG extends RT_CONFIG_SCHEME<{ development: true; - ifConditionWay: 'natural'; }> {} \ No newline at end of file