free-types-core 0.9.0 → 1.0.1

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.
@@ -0,0 +1,52 @@
1
+ import { Const } from "./Const";
2
+ import { _apply } from "./apply";
3
+ import { Next, ArrayLike } from "./utils";
4
+ import { Contra, NamedConstraints } from "./Type";
5
+ type Type = {
6
+ type: any;
7
+ constraints: any;
8
+ names: any;
9
+ arg: any;
10
+ };
11
+ type Unconstrained = {
12
+ [k: number]: unknown;
13
+ };
14
+ export type $Before<$T extends Type, $P extends ContraIndex<$P, $T, I>, I extends number = never> = [I] extends [never] ? $BeforeN<$T, $P> : $BeforeI<$T, $P, I>;
15
+ interface $BeforeI<$T extends Type, $P extends Type, I extends number, Constraints extends Unconstrained = ReplaceAt<$T['constraints'], I, Const<$P['constraints'][0]>>> extends $Type<$T> {
16
+ type: _apply<$T, ReplaceAt<this['arguments'], I, $P>>;
17
+ constraints: Constraints;
18
+ contra: Contra<Constraints>;
19
+ namedConstraints: NamedConstraints<this>;
20
+ }
21
+ interface $BeforeN<$T extends Type, $P extends Type, Constraints extends Unconstrained = $T['constraints'] extends infer I extends unknown[] ? {
22
+ [K in keyof I]: $P['constraints'][0];
23
+ } : unknown[]> extends $Type<$T> {
24
+ type: _apply<$T, this['arguments'] extends (infer I extends ArrayLike) & unknown[] ? {
25
+ [K in keyof I]: _apply<$P, [I[K]]>;
26
+ } : ArrayLike>;
27
+ constraints: Constraints;
28
+ contra: Contra<Constraints>;
29
+ namedConstraints: NamedConstraints<this>;
30
+ }
31
+ interface $Type<$T extends Type> {
32
+ [k: number]: unknown;
33
+ names: $T['names'];
34
+ arg: $T['arg'];
35
+ arguments: unknown[];
36
+ }
37
+ type ContraIndex<$T extends Type, M extends Type, I extends number, Model = [I] extends [never] ? M['constraints'][number] : M['constraints'][I]> = [Model] extends $T['constraints'] ? {
38
+ constraints: any[];
39
+ type: Model;
40
+ names: any;
41
+ arg: any;
42
+ } : {
43
+ constraints: [Model];
44
+ type: Model;
45
+ names: any;
46
+ arg: any;
47
+ };
48
+ type ReplaceAt<T extends {
49
+ [k: number]: unknown;
50
+ length: number;
51
+ }, N extends number, $P extends Type, L extends number = T['length'], I extends number = 0, R extends unknown[] = []> = I extends L ? R : ReplaceAt<T, N, $P, L, Next<I>, [...R, I extends N ? _apply<$P, [T[I]]> : T[I]]>;
52
+ export {};
package/dist/Const.d.ts CHANGED
@@ -3,24 +3,26 @@ export { Const, $Const };
3
3
  /**
4
4
  * Turn a type `T` into a constant `Type<❋, T>`, totally ignoring arity and type constraints on its input.
5
5
  */
6
- declare type Const<T> = {
6
+ type Const<T> = ConstantType<{
7
7
  type: T;
8
+ }, {
8
9
  constraints: any;
10
+ names: any;
11
+ }>;
12
+ interface ConstantType<Out extends {
13
+ type: any;
14
+ }, __> {
15
+ [k: number]: any;
16
+ type: Out['type'];
9
17
  arguments: any[] & {
10
18
  length: any;
11
19
  };
12
- labels: any;
13
- 0: any;
14
- 1: any;
15
- 2: any;
16
- 3: any;
17
- 4: any;
18
- 5: any;
19
- 6: any;
20
- 7: any;
21
- 8: any;
22
- 9: any;
23
- };
20
+ namedConstraints: any;
21
+ arg: any;
22
+ constraints: any;
23
+ names: any;
24
+ contra: any;
25
+ }
24
26
  /**
25
27
  * Turn the input into a constant `Type<❋, T>`, totally ignoring arity and type constraints on its input.
26
28
  */
package/dist/Flow.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { _apply, _Type } from './apply';
2
+ import { Type } from './Type';
3
+ import { Next } from './utils';
4
+ export { Flow };
5
+ type Flow<$Ts extends Composable, Composable extends (_Type & {
6
+ contra: any;
7
+ })[] = $Ts extends [_Type] ? [_Type] : Check<$Ts>> = Composition<{
8
+ type: Fallback<$Ts>;
9
+ constraints: $Ts[0]['constraints'];
10
+ names: $Ts[0]['names'];
11
+ }, $Ts>;
12
+ type Descriptor = {
13
+ type: any;
14
+ constraints: any;
15
+ names: any;
16
+ };
17
+ interface Composition<D extends Descriptor, $Ts extends (_Type & {
18
+ contra: any;
19
+ })[]> extends Type {
20
+ type: unknown[] extends this['arguments'] ? D['type'] : Pipe<[_apply<$Ts[0], this['arguments']>], $Ts>;
21
+ names: D['names'];
22
+ constraints: D['constraints'];
23
+ contra: $Ts[0]['contra'];
24
+ namedConstraints: $Ts[0]['namedConstraints'];
25
+ }
26
+ type Fallback<$Ts> = $Ts extends [...any, infer $T extends {
27
+ type: unknown;
28
+ }] ? $T['type'] : never;
29
+ export type Check<T extends unknown[], R extends _Type[] = [], Last extends _Type[] = []> = T extends [infer A extends _Type, infer B extends _Type, ...infer Rest] ? Check2<A, B> extends infer C extends [_Type, _Type] ? Check<Rest, [...R, ...Last, C[0]], [C[1]]> : never : T extends [infer A extends _Type, infer B extends _Type] ? [...R, ...Last, ...Check2<A, B>] : T extends [infer A extends _Type] ? Last extends [] ? [...R, A] : [...R, ...Check2<Last[0], A>] : [...R, ...Last];
30
+ type Check2<A extends _Type, B extends _Type> = A['type'] extends B['constraints'][0] ? [A, B] : [Type<A['constraints'], B['constraints'][0]>, B];
31
+ type Pipe<Args extends unknown[], $Ts extends _Type[], I extends number = 1, R = _apply<$Ts[I], Args>, N extends number = Next<I>> = N extends $Ts['length'] ? R : R extends $Ts[N]['constraints'][0] ? Pipe<[R], $Ts, N> : never;
package/dist/Flow.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/From.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ import { Contra, NamedConstraints } from './Type';
2
+ import { ArrayLike, Next, IsOptional, Mappable, Union2Tuple, Int } from './utils';
3
+ export { From };
4
+ type Named = ({
5
+ [k: PropertyKey]: string;
6
+ } | undefined)[];
7
+ type None = {};
8
+ /** Create a new `Type` based upon a Mappable `T`.
9
+ *
10
+ * Optionally take a tuple `Args` to specify which fields to turn into a parameter and in what order they must be applied. Parameters can be set to be optional. Named parameters are created automatically for object types, they can be renamed.
11
+ *
12
+ * */
13
+ type From<T extends Mappable<any>, Args extends readonly (keyof T | undefined)[] | Named = never> = ([
14
+ Args
15
+ ] extends [never] ? (T extends unknown[] ? GetIndices<T> : Union2Tuple<keyof T>) extends infer K ? {
16
+ constraints: PseudoTuple<T, K>;
17
+ names: None;
18
+ keys: K;
19
+ } : never : Args extends Named ? {
20
+ constraints: ToConstraints<T, Args>;
21
+ names: GetNames<Args>;
22
+ keys: GetKeys<Args>;
23
+ } : {
24
+ constraints: PseudoTuple<T, Args>;
25
+ names: Args extends (string | undefined)[] ? GenerateNames<Args> : {};
26
+ keys: Required<Args>;
27
+ }) extends infer D extends Descriptor ? FromTemplate<{
28
+ type: T;
29
+ }, D> : never;
30
+ type Descriptor = {
31
+ constraints: any;
32
+ names: any;
33
+ keys: any;
34
+ };
35
+ interface FromTemplate<T extends {
36
+ type: any;
37
+ }, D extends Descriptor> {
38
+ [k: number]: unknown;
39
+ type: T['type'] extends infer Type ? unknown[] extends this['arguments'] ? Type : {
40
+ [K in keyof Type]: Value<Type[K], this['arguments'], IndexOf<K, D['keys']>, D['constraints']>;
41
+ } : never;
42
+ namedConstraints: NamedConstraints<D>;
43
+ names: D['names'];
44
+ constraints: D['constraints'];
45
+ contra: Contra<D['constraints']>;
46
+ arg: any;
47
+ arguments: unknown[];
48
+ }
49
+ type GetIndices<T extends unknown[]> = {
50
+ [K in keyof T]-?: K;
51
+ };
52
+ export type Value<T, This extends ArrayLike, I, Constraints extends ArrayLike> = [
53
+ I
54
+ ] extends [never] ? T : IsOptional<Constraints, I> extends true ? This[I & number] extends undefined ? T : This[I & number] : This[I & number];
55
+ export type IndexOf<T, Ts extends ArrayLike, L = Required<Ts>['length'], I = 0> = I extends L ? never : [T] extends [`${Ts[I & number]}`] ? I : IndexOf<T, Ts, L, Next<I>>;
56
+ type PseudoTuple<T, Keys> = {
57
+ [K in keyof Keys]: Exclude<T[Keys[K] & keyof T], undefined>;
58
+ };
59
+ type ToConstraints<T, Args extends Named> = {
60
+ [K in keyof Args]: T[keyof (Args[K] & {}) & keyof T];
61
+ };
62
+ type GetKeys<Args extends Named, R = Required<Args>> = {
63
+ [K in keyof R]: keyof R[K];
64
+ };
65
+ type GetNames<Args extends Named, T extends Required<Named> = Required<Args>> = unknown & {
66
+ [K in keyof T as T[K & `${number}`][keyof T[K]]]: Int<K>;
67
+ };
68
+ type GenerateNames<Args extends (string | undefined)[]> = unknown & {
69
+ [K in Exclude<keyof Args, keyof []> as Args[K] & string]: Int<K>;
70
+ };
package/dist/From.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/Pipe.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { Next } from "./utils";
2
+ import { _apply, apply, _Type as Type } from './apply';
3
+ type _Type<C = any> = {
4
+ type: any;
5
+ constraints: C;
6
+ };
7
+ type TooManyArgs = 'You can compose up to 10 free types with Pipe';
8
+ type WrongArg = 'would be called with wrong argument';
9
+ /** Pipe an arguments list or named arguments through a composition of free types
10
+ * ```
11
+ * type Foo = Pipe<[1, 2], $Add, $Next, $Exclaim> // "4!"
12
+ * ```
13
+ * ---
14
+ * **Note**: Error messages are narrower than they need to be:
15
+ * ```
16
+ * Pipe<['foo'], $Exclain, $Next>
17
+ * // ~~~~~
18
+ * // Type<[number], number>' does not satisfy the constraint 'Type<["foo!"], number>
19
+ * ```
20
+ * Understand it as `Type<[number], number>` would be called with wrong argument `"foo!"`. This inconvenience is required for generic higher order compositions to work properly.
21
+ */
22
+ export type Pipe<Args extends [STOP] extends [never] ? Check : TooManyArgs, A extends Type = never, B extends _<B, WrongArg, RA> = never, C extends _<C, WrongArg, RB> = never, D extends _<D, WrongArg, RC> = never, E extends _<E, WrongArg, RD> = never, F extends _<F, WrongArg, RE> = never, G extends _<G, WrongArg, RF> = never, H extends _<H, WrongArg, RG> = never, I extends _<I, WrongArg, RH> = never, J extends _<J, WrongArg, RI> = never, STOP = never, RA = apply<A, Args, any>, RB = _apply<B, [RA]>, RC = _apply<C, [RB]>, RD = _apply<D, [RC]>, RE = _apply<E, [RD]>, RF = _apply<F, [RE]>, RG = _apply<G, [RF]>, RH = _apply<H, [RG]>, RI = _apply<I, [RH]>, RJ = _apply<J, [RI]>, Check = Args extends readonly unknown[] ? A['constraints'] : A['namedConstraints']> = Result<[RA, RB, RC, RD, RE, RF, RG, RH, RI, RJ]>;
23
+ type Result<T extends unknown[], I extends number = 0, R = never> = [
24
+ T[I]
25
+ ] extends [never] ? R : I extends T['length'] ? R : Result<T, Next<I>, T[I]>;
26
+ type _<$T extends _Type, _, $U> = [$U] extends $T['constraints'] ? any : _Type<[$U]>;
27
+ export {};
package/dist/Pipe.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/Replace.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { unwrap, Unwrapped, Search } from './unwrap';
2
- import { apply } from './apply';
2
+ import { _apply } from './apply';
3
3
  import { TypesMap } from './TypesMap';
4
4
  export { Replace };
5
5
  /** Replace the inner value of a type with compatible arguments.
6
6
  *
7
7
  * Can be used to constrain the inner value of a type
8
8
  */
9
- declare type Replace<T, Args extends U['type']['constraints'], From extends Search = TypesMap, U extends Unwrapped = unwrap<T, From>> = apply<U['type'], Args>;
9
+ type Replace<T, Args extends U['type']['constraints'], From extends Search = TypesMap, U extends Unwrapped = unwrap<T, From>> = _apply<U['type'], Args>;
package/dist/Type.d.ts CHANGED
@@ -1,32 +1,83 @@
1
- import { Tuple } from './utils';
2
- export { Type };
3
- /** Extend `Type<Input?, Output?>` with an interface to produce a free type, or use it as a type constraint.*/
4
- declare type Type<Input extends number | unknown[] = unknown[], Output = unknown, Labels extends string[] = []> = CreateType<{
5
- type: Output;
6
- constraints: Constraints<Input, Slots<Input>>;
7
- arguments: unknown[];
8
- labels: ReverseMap<Labels>;
1
+ import { Tuple, ToTuple, Int, Slice, ArrayLike, ArrayKeys, OptionalKeys, IsAny, NumericKeys } from './utils';
2
+ export { Type, Input, Arg, NamedConstraints, Contra };
3
+ /** Extend `Type<Input?, Output?>` with an interface to produce a free type, or use it as a type constraint.
4
+ */
5
+ type Type<In extends Input = any, Out = unknown> = CreateType<{
6
+ type: Out;
7
+ }, {
8
+ constraints: Constraints<In>;
9
+ names: In extends Detailed ? {
10
+ [K in Exclude<keyof In, symbol>]: GetIndex<In[K]>;
11
+ } : None;
9
12
  }>;
10
- interface CreateType<T extends {
11
- type: unknown;
12
- constraints: unknown[];
13
- labels: {
14
- [k: string]: number;
15
- };
16
- }> {
13
+ type None = {};
14
+ type Descriptor = {
15
+ constraints: any;
16
+ names: any;
17
+ };
18
+ type Input = number | readonly unknown[] | PseudoTuple | Detailed;
19
+ type PseudoTuple = {
20
+ [k: number]: any;
21
+ length?: number;
22
+ };
23
+ type Detailed = {
24
+ [k: string]: [index: number, constraint?: unknown] | number;
25
+ [k: number]: never;
26
+ };
27
+ interface CreateType<Out extends {
28
+ type: any;
29
+ }, T extends Descriptor> {
17
30
  [k: number]: unknown;
18
- type: T['type'];
31
+ type: Out['type'];
19
32
  constraints: T['constraints'];
33
+ contra: Contra<T['constraints']>;
34
+ namedConstraints: NamedConstraints<T>;
35
+ arg: Arg<this>;
20
36
  arguments: unknown[];
21
- labels: T['labels'];
37
+ names: T['names'];
22
38
  }
23
- declare type ReverseMap<T extends string[]> = {
24
- [K in keyof T as K extends `${number}` ? T[K] : never]: K extends `${infer I extends number}` ? I : never;
39
+ type Contra<T extends Variadic> = any[] extends T ? IsAny<T[number]> extends true ? (constraints: any) => void : (constraints: {
40
+ [k: number]: T[number];
41
+ }) => void : NumericKeys<T> extends infer Keys extends number ? Int<OptionalKeys<T>> extends infer O extends number ? (constraints: unknown & {
42
+ [K in Keys as K extends O ? never : K]: T[K];
43
+ } & {
44
+ [K in Keys as K extends O ? K : never]?: T[K];
45
+ }) => void : never : never;
46
+ type NamedConstraints<T extends {
47
+ constraints: any;
48
+ names: any;
49
+ }, O = Int<OptionalKeys<T['constraints']>>> = {
50
+ [K in keyof T['names'] as T['names'][K] extends O ? never : K]: T['constraints'][T['names'][K]];
51
+ } & {
52
+ [K in keyof T['names'] as T['names'][K] extends O ? K : never]?: T['constraints'][T['names'][K]];
53
+ };
54
+ type _Type = {
55
+ [k: number]: unknown;
56
+ constraints: ArrayLike;
57
+ names: {
58
+ [k: string]: number;
59
+ };
60
+ };
61
+ type Arg<This extends _Type, Args = This['names'] & This['constraints'], O extends PropertyKey = FindOptionalKeys<This['constraints'], This['names']>, R extends PropertyKey = Exclude<Norm<Exclude<keyof Args, ArrayKeys>>, O>> = {
62
+ [K in Norm<R>]: ArgVal<This, K>;
63
+ } & {
64
+ [K in Norm<O>]?: ArgVal<This, K>;
25
65
  };
26
- declare type Slots<T> = T extends Precomputable ? PrecomputedSlots[T & Precomputable] : Tuple<T extends unknown[] ? T['length'] : T extends number ? T : number>;
27
- declare type Constraints<Input, Slots> = number extends Input ? unknown[] : unknown[] extends Input ? unknown[] : Input extends unknown[] ? Input : Slots;
28
- declare type PrecomputedSlots = {
29
- [I in Precomputable]: Tuple<Seq10[I]>;
66
+ type FindOptionalKeys<Constraints, Names, O = Int<OptionalKeys<Constraints>>> = O | (keyof {
67
+ [K in keyof Names as Names[K] extends O ? K : never]: never;
68
+ });
69
+ type ArgVal<This extends _Type, K> = K extends `${number}` | number ? Int<K> extends infer Key extends number ? GetValue<This, Key> : never : K extends string ? GetValue<This, This['names'][K]> : never;
70
+ type GetValue<This extends _Type, I extends number> = This['constraints'][I] extends infer Constraint ? This[I] extends Constraint ? This[I] : Constraint & This[I] : never;
71
+ type Norm<T> = T extends `${number}` ? Int<T> : T;
72
+ type Unconstrained = {
73
+ [k: number]: any;
30
74
  };
31
- declare type Precomputable = Seq10[number];
32
- declare type Seq10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
75
+ type Variadic = {
76
+ [k: number]: unknown;
77
+ };
78
+ type Constraints<T> = IsAny<T> extends true ? Unconstrained : unknown[] extends T ? IsAny<Extract<T, unknown[]>[number]> extends true ? Unconstrained : Variadic : readonly unknown[] extends T ? Variadic : T extends readonly unknown[] ? T : T extends number ? number extends T ? Variadic : Tuple<T, any> : T extends Detailed ? DetailedToConstraints<T> : T extends PseudoTuple ? T extends ArrayLike ? Slice<T, 0, T['length']> : ToTuple<T> : Variadic;
79
+ type DetailedToConstraints<T extends Detailed> = ToTuple<{
80
+ [K in keyof T as GetIndex<T[K]>]: GetConstraint<T[K]>;
81
+ }>;
82
+ type GetIndex<T> = Exclude<T extends [infer N extends number, any?] ? N : T, undefined>;
83
+ type GetConstraint<T> = Exclude<T, undefined> extends [any, infer C] ? C : unknown;
@@ -0,0 +1,15 @@
1
+ export { TypeDoc };
2
+ type Type = {
3
+ type: any;
4
+ constraints: any;
5
+ names: any;
6
+ };
7
+ type TypeDoc<$T extends Type> = CreateType<{
8
+ type: $T['type'];
9
+ }, {
10
+ constraints: $T['constraints'];
11
+ names: $T['names'];
12
+ }, $T>;
13
+ /** @ts-ignore: Nasty hack */
14
+ interface CreateType<_, __, $T extends {}> extends $T {
15
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/apply.d.ts CHANGED
@@ -1,46 +1,49 @@
1
1
  import { Type } from './Type';
2
- import { ArrayKeys, Next } from './utils';
3
- declare type NamedType = {
2
+ import { ArrayLike, ArrayKeys, Indexable, Next } from './utils';
3
+ export { apply, _apply, _applyPositional as applyPositional, $apply, Generic, _Type };
4
+ /** A type definition to be used as a type constraint in internal library code to improve performance */
5
+ type _Type<I = any, O = unknown> = {
6
+ type: O;
7
+ constraints: I;
8
+ names: any;
9
+ namedConstraints: any;
10
+ };
11
+ type PositionalType = {
4
12
  type: unknown;
5
- constraints: {
6
- [k: number]: unknown;
7
- length: number;
8
- };
9
- labels: Labels;
13
+ constraints: Indexable;
10
14
  };
11
- declare type Labels = {
15
+ type Names = {
12
16
  [k: string]: number;
13
17
  };
14
- export { apply, applyNamed, $apply, Generic };
15
- /** Apply a free type with its complete arguments list and evaluate the type */
16
- declare type apply<$T extends Type, Args extends $T['constraints'] = []> = applyPositional<$T, Args>;
17
- /** Apply a free type with its complete arguments struct and evaluate the type */
18
- declare type applyNamed<$T extends NamedType, Args extends CheckNamed<$Model>, $Model extends NamedType = $T> = applyPositional<$T, ToPositional<$T, Args>>;
19
- declare type RecoverLabels<T extends Labels> = {
20
- [K in keyof T as T[K]]: K;
21
- };
22
- declare type ToPositional<$T extends NamedType, Args extends {
18
+ /** Apply a free type with all its arguments and evaluate the type */
19
+ type apply<$T extends _Type, Args extends Check = never, Check = Args extends ArrayLike ? $T['constraints'] : $T['namedConstraints']> = applyPositional<$T, ([
20
+ Args
21
+ ] extends [never] ? [] : Args extends ArrayLike ? Args : Args extends {
22
+ [k: string]: unknown;
23
+ } ? ToPositional<GetLength<$T['constraints']>, Args, RecoverNames<$T['names']>> : [])>;
24
+ type GetLength<T> = Extract<T extends ArrayLike ? T['length'] : number, number>;
25
+ type _applyPositional<$T extends PositionalType, Args extends $T['constraints'] = []> = applyPositional<$T, Args>;
26
+ type ToPositional<L extends number, Args extends {
23
27
  [k: string]: unknown;
24
- }, Labels extends {
28
+ }, Names extends {
25
29
  [k: number]: string;
26
- } = RecoverLabels<$T['labels']>, I extends number = 0, R extends unknown[] = []> = I extends $T['constraints']['length'] ? R : ToPositional<$T, Args, Labels, Next<I>, [...R, Args[Labels[I]]]>;
27
- declare type CheckNamed<$T extends NamedType> = {
28
- [K in keyof $T['labels']]: $T['constraints'][$T['labels'][K]];
30
+ }, I extends number = 0, R extends any[] = []> = I extends L ? R : ToPositional<L, Args, Names, Next<I>, [...R, Args[Names[I]]]>;
31
+ type RecoverNames<T extends Names> = {
32
+ [K in keyof T as T[K]]: K;
29
33
  };
30
- interface $apply<Args extends unknown[] = []> extends Type<[Type]> {
31
- type: apply<this[0] extends Type ? this[0] : Type, Args>;
34
+ interface $apply<Args extends ArrayLike = []> extends Type<[_Type]> {
35
+ type: this[0] extends _Type ? _apply<this[0], Args> : unknown;
32
36
  }
33
37
  /** Apply a free type `$T` with its type constraints. */
34
- declare type Generic<$T extends Type> = _apply<$T, $T['constraints']>;
35
- declare type applyPositional<$T extends {
36
- type: unknown;
37
- constraints: {
38
- length: number;
39
- };
40
- }, Args extends unknown[]> = number extends $T['constraints']['length'] ? _apply<$T, Args> : _apply<$T, Take<Args, Required<$T['constraints']>['length']>>;
41
- declare type _apply<T extends {
38
+ type Generic<$T extends _Type> = _apply<$T, $T['constraints']>;
39
+ type applyPositional<$T extends PositionalType, Args extends Indexable> = number extends GetLength<$T['constraints']> ? _apply<$T, Args> : _apply<$T, Take<Args, 0, GetLength<Required<$T['constraints']>>>>;
40
+ /** A looser version of `apply` which can be used in internal library code to improve performance */
41
+ type _apply<$T extends {
42
42
  type: unknown;
43
- }, Args> = (T & Omit<Args, ArrayKeys> & {
43
+ }, Args extends _Constraints> = ($T & Omit<Args, ArrayKeys> & {
44
44
  arguments: Args;
45
45
  })['type'];
46
- declare type Take<T extends unknown[], To extends number, I extends number = 0, R extends unknown[] = []> = I extends To ? R : Take<T, To, Next<I>, [...R, T[I]]>;
46
+ type _Constraints = {
47
+ [k: number]: unknown;
48
+ };
49
+ type Take<T extends Indexable, From extends number, To, R extends any[] = []> = From extends To ? R : Take<T, Next<From>, To, [...R, T[From]]>;
@@ -1,38 +1,40 @@
1
1
  import { Type } from './Type';
2
- import { ToTuple } from './utils';
2
+ type ToTuple<T> = T extends infer I extends unknown[] & unknown[] ? I : never;
3
3
  export { $Id as Id, $Record as Record, $Array as Array, $Tuple as Tuple, $ReadonlyTuple as ReadonlyTuple, $ReadonlyArray as ReadonlyArray, $Set as Set, $ReadonlySet as ReadonlySet, $WeakSet as WeakSet, $Map as Map, $ReadonlyMap as ReadonlyMap, $WeakMap as WeakMap, $Function as Function, $UnaryFunction as UnaryFunction, $Promise as Promise };
4
- interface $Id extends Type<1> {
4
+ type $Unary = Type<1>;
5
+ type $Binary = Type<2>;
6
+ type $Variadic = Type;
7
+ interface $Id extends $Unary {
5
8
  type: this[0];
6
9
  }
7
- declare type Key = string | number | symbol;
8
- interface $Record extends Type<[Key, unknown]> {
9
- type: Record<this[0] & Key, this[1]>;
10
+ interface $Record extends Type<[PropertyKey, unknown]> {
11
+ type: Record<this[0] & PropertyKey, this[1]>;
10
12
  }
11
- interface $Array extends Type<1> {
13
+ interface $Array extends $Unary {
12
14
  type: Array<this[0]>;
13
15
  }
14
- interface $Tuple extends Type {
16
+ interface $Tuple extends $Variadic {
15
17
  type: ToTuple<this['arguments']>;
16
18
  }
17
- interface $ReadonlyTuple extends Type {
18
- type: Readonly<ToTuple<this['arguments']>>;
19
+ interface $ReadonlyTuple extends $Variadic {
20
+ type: readonly [...ToTuple<this['arguments']>];
19
21
  }
20
- interface $ReadonlyArray extends Type<1> {
22
+ interface $ReadonlyArray extends $Unary {
21
23
  type: ReadonlyArray<this[0]>;
22
24
  }
23
- interface $Set extends Type<1> {
25
+ interface $Set extends $Unary {
24
26
  type: Set<this[0]>;
25
27
  }
26
- interface $ReadonlySet extends Type<1> {
28
+ interface $ReadonlySet extends $Unary {
27
29
  type: ReadonlySet<this[0]>;
28
30
  }
29
31
  interface $WeakSet extends Type<[object]> {
30
32
  type: WeakSet<this[0] extends object ? this[0] : object>;
31
33
  }
32
- interface $Map extends Type<2> {
34
+ interface $Map extends $Binary {
33
35
  type: Map<this[0], this[1]>;
34
36
  }
35
- interface $ReadonlyMap extends Type<2> {
37
+ interface $ReadonlyMap extends $Binary {
36
38
  type: ReadonlyMap<this[0], this[1]>;
37
39
  }
38
40
  interface $WeakMap extends Type<[object, unknown]> {
@@ -41,10 +43,10 @@ interface $WeakMap extends Type<[object, unknown]> {
41
43
  interface $Function extends Type<[any[], unknown]> {
42
44
  type: (...args: this[0] extends any[] ? this[0] : any[]) => this[1];
43
45
  }
44
- interface $UnaryFunction extends Type<2> {
46
+ interface $UnaryFunction extends $Binary {
45
47
  type: (a: unknown extends this[0] ? any : this[0]) => this[1];
46
48
  }
47
- interface $Promise extends Type<1> {
49
+ interface $Promise extends $Unary {
48
50
  type: Promise<this[0]>;
49
51
  }
50
52
  declare global {
package/dist/helpers.d.ts CHANGED
@@ -1,74 +1,99 @@
1
- import { Next, IsUnknown, Prev } from './utils';
2
- export { At, Checked, Lossy, Optional, A, B, C, D, E };
3
- declare type Type<N extends number = number> = {
4
- constraints: N extends number ? {
5
- [K in Prev<N>]: unknown;
6
- } : unknown[];
7
- arguments: unknown[];
8
- labels: {
9
- [k: string]: number;
10
- };
11
- };
12
- declare type Type_<N extends number> = {
1
+ import { Next, IsUnknown, Prev, OptionalKeys } from './utils';
2
+ export { Get, At, Checked, Lossy, Optional, A, B, C, D, E, Applied, Valid };
3
+ /** Fake `Type` for user friendly error messages */
4
+ interface Type<In extends number | Names> extends BaseType {
5
+ arg: Constraints<In>;
6
+ constraints: Constraints<In>;
7
+ names: In extends number ? any : In;
8
+ }
9
+ type Constraints<In> = In extends number ? {
10
+ [K in Prev<In>]: unknown;
11
+ } : any;
12
+ /** Fake `Type` for user friendly error messages */
13
+ interface OptionalType<In extends number | Names> extends BaseType {
14
+ constraints: Partial<Constraints<In>>;
15
+ names: In extends number ? any : In;
16
+ }
17
+ /** fast Type definition */
18
+ interface BaseType {
13
19
  constraints: {
14
- [K in Prev<N>]?: unknown;
20
+ [k: number]: unknown;
15
21
  };
16
- arguments: unknown[];
17
- labels: {
18
- [k: string]: number;
22
+ arguments: {
23
+ [k: number]: unknown;
19
24
  };
25
+ names: Names;
26
+ }
27
+ type Names = {
28
+ [k: string]: number;
20
29
  };
21
- declare type Default = {
22
- constraints: [0, 1, 2, 3, 4];
23
- arguments: unknown[];
24
- labels: {
25
- [k: string]: number;
26
- };
30
+ type Normalise<Index extends string | number> = Index extends number ? Next<Index> : {
31
+ [K in Index]: number;
27
32
  };
33
+ /** tell whether a Type is applied with all its arguments or not */
34
+ type Applied<This extends {
35
+ arguments: any;
36
+ }> = unknown[] extends This['arguments'] ? false : true;
37
+ /** tell whether a Type is applied with all the correct arguments */
38
+ type Valid<This extends {
39
+ arguments: any;
40
+ constraints: any;
41
+ }> = Applied<This> extends false ? false : This['arguments'] extends This['constraints'] ? true : false;
42
+ /** safely index `this` */
43
+ type Get<K extends keyof This['arg'], This extends {
44
+ arg: any;
45
+ }> = K extends OptionalKeys<This['arg']> ? Exclude<This['arg'][K], undefined> : This['arg'][K];
28
46
  /** - safely index `this`
29
47
  * - optionally take a fallback
30
48
  */
31
- declare type At<N extends Check, This extends N extends number ? Type<Next<N>> : Type, Fallback = unknown, Check extends string | number = N extends string ? keyof This['labels'] & string : number> = N extends number ? AtImpl<This, Fallback, N> : AtImpl<This, Fallback, This['labels'][N]>;
32
- declare type AtImpl<This extends Type, Fallback, I extends number> = IsUnknown<This['arguments'][I]> extends true ? Fallback : This['arguments'][I];
49
+ type At<Index extends string | number, This extends Type<Normalise<Index>>, Fallback = unknown, I extends number = Index extends number ? Index : This['names'][Index]> = IsUnknown<This['arguments'][I]> extends true ? Fallback : This['arguments'][I];
33
50
  /** - safely index `this`
34
51
  * - defuse the corresponding type constraint with an inline conditional
35
52
  * - optionally take a fallback
36
53
  */
37
- declare type Checked<N extends Check, This extends N extends number ? Type<Next<N>> : Type, Fallback = N extends number ? This['constraints'][N] : N extends string ? This['constraints'][This['labels'][N]] : never, Check extends string | number = N extends string ? keyof This['labels'] & string : number> = N extends number ? CheckedImpl<N, This, Fallback> : CheckedImpl<This['labels'][N], This, Fallback>;
38
- declare type CheckedImpl<N extends number, This extends Type, Fallback> = This['arguments'][N] extends This['constraints'][N] ? This['arguments'][N] : Fallback;
54
+ type Checked<Index extends string | number, This extends Type<Normalise<Index>>, Fallback = Index extends number ? This['constraints'][Index] : This['constraints'][This['names'][Index]], I extends number = Index extends number ? Index : This['names'][Index]> = This['arguments'][I] extends This['constraints'][I] ? This['arguments'][I] : Fallback;
39
55
  /** - safely index `this`
40
56
  * - works on optional parameters
41
57
  * - defuse the corresponding type constraint with an inline conditional
42
58
  * - optionally take a fallback
43
59
  */
44
- declare type Optional<N extends Check, This extends N extends number ? Type_<Next<N>> : Type, Fallback = N extends number ? Exclude<This['constraints'][N], undefined> : N extends string ? Exclude<This['constraints'][This['labels'][N]], undefined> : never, Check extends string | number = N extends string ? keyof This['labels'] & string : number> = N extends number ? OptionalImpl<N, This, Fallback> : OptionalImpl<This['labels'][N], This, Fallback>;
45
- declare type OptionalImpl<N extends number, This extends Type, Fallback> = This['arguments'][N] extends Exclude<This['constraints'][N], undefined> ? This['arguments'][N] : Fallback;
60
+ type Optional<Index extends string | number, This extends OptionalType<Normalise<Index>>, Fallback = Index extends number ? Exclude<This['constraints'][Index], undefined> : Exclude<This['constraints'][This['names'][Index]], undefined>, I extends number = Index extends number ? Index : This['names'][Index]> = This['arguments'][I] extends Exclude<This['constraints'][I], undefined> ? This['arguments'][I] : Fallback;
46
61
  /** - safely index `this`
47
62
  * - intersect the corresponding type constraint
48
63
  */
49
- declare type Lossy<N extends Check, This extends N extends number ? Type<Next<N>> : Type, Check extends string | number = N extends string ? keyof This['labels'] & string : number> = N extends number ? This['arguments'][N] & This['constraints'][N] : This['arguments'][This['labels'][N]] & This['constraints'][This['labels'][N]];
64
+ type Lossy<Index extends string | number, This extends Type<Normalise<Index>>, I extends number = Index extends number ? Index : This['names'][Index]> = This['arguments'][I] & This['constraints'][I];
65
+ interface NumericValue extends BaseType {
66
+ constraints: any;
67
+ arg: {
68
+ 0: 0;
69
+ 1: 1;
70
+ 2: 2;
71
+ 3: 3;
72
+ 4: 4;
73
+ };
74
+ }
50
75
  /** - safely index `this`
51
76
  * - intersect the corresponding type constraint
52
77
  * - equals `0` When no argument is supplied
53
78
  */
54
- declare type A<This extends Type<1> = Default> = This['arguments'][0] & This['constraints'][0];
79
+ type A<This extends Type<1> = NumericValue> = Get<0, This>;
55
80
  /** - safely index `this`
56
81
  * - intersect the corresponding type constraint
57
82
  * - equals `1` When no argument is supplied
58
83
  */
59
- declare type B<This extends Type<2> = Default> = This['arguments'][1] & This['constraints'][1];
84
+ type B<This extends Type<2> = NumericValue> = Get<1, This>;
60
85
  /** - safely index `this`
61
86
  * - intersect the corresponding type constraint
62
87
  * - equals `2` When no argument is supplied
63
88
  */
64
- declare type C<This extends Type<3> = Default> = This['arguments'][2] & This['constraints'][2];
89
+ type C<This extends Type<3> = NumericValue> = Get<2, This>;
65
90
  /** - safely index `this`
66
91
  * - intersect the corresponding type constraint
67
92
  * - equals `3` When no argument is supplied
68
93
  */
69
- declare type D<This extends Type<4> = Default> = This['arguments'][3] & This['constraints'][3];
94
+ type D<This extends Type<4> = NumericValue> = Get<3, This>;
70
95
  /** - safely index `this`
71
96
  * - intersect the corresponding type constraint
72
97
  * - equals `4` When no argument is supplied
73
98
  */
74
- declare type E<This extends Type<5> = Default> = This['arguments'][4] & This['constraints'][4];
99
+ type E<This extends Type<5> = NumericValue> = Get<4, This>;
package/dist/hkt.d.ts CHANGED
@@ -1,19 +1,15 @@
1
- import { Type } from "./Type";
2
- export { HKT, Contra };
1
+ import { _Type } from "./apply";
2
+ export { HKT, Contra, Expect };
3
3
  /** Interfaces extending this type are able to use `hkt` internally. */
4
- declare type HKT = {
4
+ type HKT = {
5
5
  HKT: [any, ...any[]];
6
6
  };
7
- /** Expect a free type with contravariant arguments */
8
- declare type Contra<$T, $U extends Type> = Type & _Contra<$T, $U>['type'];
9
- interface _Contra<$T, $U extends Type> {
10
- type: $U['constraints'] extends this['$T']['constraints'] ? this['$T']['type'] extends $U['type'] ? Type : Type<this['$T']['constraints'], $U['type']> : {
11
- [K in 'Contravariance issue']: [
12
- 'the input',
13
- $U['constraints'],
14
- 'is not assignable to',
15
- this['$T']['constraints']
16
- ];
17
- };
18
- $T: $T extends Type ? $T : never;
19
- }
7
+ /** Expect a free type with contravariant arguments
8
+ * @deprecated use `Expect` instead
9
+ * */
10
+ type Contra<$T, $U extends _Type> = _Contra<Extract<$T, _Type>, $U>;
11
+ type _Contra<$T extends _Type, $U extends _Type> = $U['constraints'] extends $T['constraints'] ? $T['type'] extends $U['type'] ? _Type : _Type<$T['constraints'], $U['type']> : _Type<[$U['constraints'], 'is not assignable to', $T['constraints']]>;
12
+ type Expect<$T, Active extends boolean = true> = Active extends false ? $T : {
13
+ [K in keyof $T]: K extends CovariantKey ? any : $T[K];
14
+ };
15
+ type CovariantKey = 'namedConstraints' | 'constraints' | 'arg' | 'names';
package/dist/index.d.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  export * from './apply';
2
2
  export * from './partial';
3
- export * from './Remaining';
4
- export * from './Type';
3
+ export { Type, Input } from './Type';
4
+ export * from './TypeDoc';
5
5
  export * from './Const';
6
+ export { From } from './From';
7
+ export { Flow } from './Flow';
8
+ export * from './$Before';
9
+ export * from './Pipe';
6
10
  export * from './helpers';
7
11
  export * from './inferArgs';
8
12
  export * from './unwrap';
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  export * from './apply';
2
2
  export * from './partial';
3
- export * from './Remaining';
4
- export * from './Type';
3
+ export * from './TypeDoc';
5
4
  export * from './Const';
5
+ export * from './$Before';
6
+ export * from './Pipe';
6
7
  export * from './helpers';
7
8
  export * from './inferArgs';
8
9
  export * from './unwrap';
@@ -1,7 +1,6 @@
1
- import { Type } from './Type';
2
- import { apply } from './apply';
1
+ import { _apply, _Type } from './apply';
3
2
  export { inferArgs };
4
- declare type inferArgs<T, $T extends Type> = T extends apply<$T, [
3
+ type inferArgs<T, $T extends _Type> = T extends _apply<$T, [
5
4
  infer A,
6
5
  infer B,
7
6
  infer C,
package/dist/partial.d.ts CHANGED
@@ -1,20 +1,55 @@
1
- import { Type } from './Type';
2
- import { apply } from './apply';
3
- import { Slice, Subtract, ToTuple } from './utils';
1
+ import { Arg, Type, NamedConstraints, Contra } from './Type';
2
+ import { _apply, _Type } from './apply';
3
+ import { ArrayKeys, ArrayLike, Int, Next, Slice, Subtract, Tuple } from './utils';
4
4
  export { partial, partialRight, PartialRight, $partial };
5
5
  export { PartialType };
6
- /** Return a new type based upon `$T`, with `Args` already applied, expecting the remaining arguments */
7
- declare type partial<$T extends Type, Args extends Partial<$Model['constraints']>, $Model extends Type = $T> = $T extends $Model ? Args extends unknown[] ? _partial<$T, Args> : never : never;
6
+ /** Return a new type based upon `$T`, with `Args` already applied, expecting the constraints arguments */
7
+ type partial<$T extends _Type, Args extends Partial<$Model['constraints']>, $Model extends _Type = $T> = $T extends $Model ? Args extends unknown[] ? _partial<$T, Args> : never : never;
8
8
  /** A free version of `partial` */
9
- interface $partial<$T extends Type> extends Type<1> {
9
+ interface $partial<$T extends _Type> extends Type<1> {
10
10
  type: _partial<$T, [this['arguments'][0]]>;
11
11
  }
12
- declare type _partial<$T extends Type, Args extends unknown[]> = PartialType<$T, Args, Slice<$T['constraints'], Args['length'], Required<$T['constraints']>['length']>, 'left'>;
12
+ type _partial<$T extends _Type, Args extends ArrayLike, From extends number = Args['length'], To = Required<$T['constraints']>['length']> = PartialType<{
13
+ type: $T['type'];
14
+ constraints: Slice<$T['constraints'], From, To>;
15
+ names: FilterNamesLeft<$T['names'], Args>;
16
+ applied: Args;
17
+ direction: 'left';
18
+ }, $T>;
19
+ type FilterNamesLeft<T, Args extends ArrayLike> = unknown & {
20
+ [K in keyof T as T[K] extends Int<Exclude<keyof Args, ArrayKeys>> ? never : K]: Subtract<T[K] & number, Args['length']>;
21
+ };
13
22
  /** Return a new type based upon `$T`, with `Args` already applied to the rightmost parameters of `$T`, and expecting the remaining arguments */
14
- declare type partialRight<$T extends Type, Args extends PartialRight<$Model['constraints']>, $Model extends Type = $T> = $T extends $Model ? PartialType<$T, Args, Slice<$T['constraints'], 0, Subtract<Required<$T['constraints']>['length'], Args['length']>>, 'right'> : never;
15
- declare type PartialRight<T extends unknown[], R = never> = T extends [unknown, ...(infer Rest)] ? PartialRight<Rest, T | R> : [] | R;
16
- interface PartialType<$T extends Type, Applied extends unknown[], Constraints extends unknown[], Direction> extends Type {
17
- type: apply<$T, Direction extends 'left' ? [...Applied, ...ToTuple<this['arguments']>] : [...ToTuple<this['arguments']>, ...Applied]>;
23
+ type partialRight<$T extends _Type, Args extends PartialRight<$Model['constraints']>, $Model extends _Type = $T> = $T extends $Model ? _partialRight<$T, Args, Subtract<Required<$T['constraints']>['length'], Args['length']>> : never;
24
+ type _partialRight<$T extends _Type, Args extends ArrayLike, To> = Slice<$T['constraints'], 0, To> extends infer Constraints ? PartialType<{
25
+ type: $T['type'];
18
26
  constraints: Constraints;
27
+ names: FilterNamesRight<$T['names'], Constraints>;
28
+ applied: Args;
29
+ direction: 'right';
30
+ }, $T> : never;
31
+ type FilterNamesRight<T, Args> = unknown & {
32
+ [K in keyof T as T[K] extends Int<Exclude<keyof Args, ArrayKeys>> ? K : never]: T[K];
33
+ };
34
+ type PartialRight<T extends unknown[], R = never> = T extends [unknown, ...(infer Rest)] ? PartialRight<Rest, T | R> : [] | R;
35
+ type Descriptor = {
36
+ applied: any;
37
+ direction: any;
38
+ constraints: any;
39
+ names: any;
40
+ };
41
+ interface PartialType<D extends Descriptor, $T extends _Type> {
42
+ [k: number]: unknown;
43
+ type: _apply<$T, D['direction'] extends 'left' ? [...D['applied'], ...Complement<this['arguments'], D['constraints']>] : [...Complement<this['arguments'], D['constraints']>, ...D['applied']]>;
44
+ names: D['names'];
45
+ namedConstraints: NamedConstraints<{
46
+ names: D['names'];
47
+ constraints: D['constraints'];
48
+ }>;
49
+ arg: Arg<this>;
50
+ constraints: D['constraints'];
51
+ contra: Contra<D['constraints']>;
19
52
  arguments: unknown[];
20
53
  }
54
+ type Complement<Args extends unknown[], Constraints extends unknown[]> = unknown[] extends Args ? Tuple<Constraints['length']> : _Complement<Constraints['length'], Args['length'], Args extends unknown[] & infer I extends unknown[] ? I : never>;
55
+ type _Complement<L, I, R extends unknown[]> = I extends L ? R : _Complement<L, Next<I>, [...R, unknown]>;
package/dist/unwrap.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { ArrayKeys, Eq, And, Extends, Not, IsAny } from './utils';
1
+ import { ArrayKeys, Eq, IsAny } from './utils';
2
2
  import { Type } from './Type';
3
3
  import { inferArgs } from './inferArgs';
4
- import { Generic, apply } from './apply';
4
+ import { Generic, _apply, _Type } from './apply';
5
5
  import { TypesMap } from './TypesMap';
6
6
  import { Tuple, ReadonlyTuple, Array, ReadonlyArray } from './free-types';
7
- declare type Search = Type | SearchList;
8
- declare type SearchList = Type[] | Record<string, Type> | Interface;
9
- declare type Interface = {
7
+ type Search = _Type | SearchList;
8
+ type SearchList = _Type[] | Record<string, _Type> | Interface;
9
+ type Interface = {
10
10
  [k: string]: any;
11
11
  } & {
12
12
  [Symbol.toStringTag]?: never;
@@ -22,21 +22,17 @@ declare global {
22
22
  }
23
23
  export { unwrap, Unwrapped, Search };
24
24
  /** Decompose a type into its constituents */
25
- declare type unwrap<T, From extends Search = TypesMap> = IsAny<T> extends true ? Any : And<Extends<T, readonly unknown[]>, Not<Extends<From, Type | Type[]>>> extends true ? unwrapLists<T extends readonly unknown[] ? T : never> : _unwrap<T, From extends Type ? [From] : From>;
26
- declare type unwrapLists<T> = T extends unknown[] ? T extends [unknown, ...unknown[]] ? Unwrapped<'Tuple', Tuple, T> : Unwrapped<'Array', Array, [T[0]]> : T extends readonly [unknown, ...unknown[]] ? Unwrapped<'ReadonlyTuple', ReadonlyTuple, Mutable<T>> : Unwrapped<'ReadonlyArray', ReadonlyArray, [(T & unknown[])[0]]>;
27
- declare type Mutable<T> = {
28
- -readonly [K in keyof T]: K extends ArrayKeys ? T[K] : T[K];
25
+ type unwrap<T, From extends Search = TypesMap> = IsAny<T> extends true ? Any : (T extends readonly unknown[] ? From extends _Type | _Type[] ? null : unwrapLists<T> : null) extends infer R extends Unwrapped ? R : _unwrap<T, From extends _Type ? [From] : From>;
26
+ type unwrapLists<T extends readonly unknown[]> = T extends unknown[] ? any[] extends T ? Unwrapped<'Array', Array, [T[0]]> : Unwrapped<'Tuple', Tuple, T> : readonly any[] extends T ? Unwrapped<'ReadonlyArray', ReadonlyArray, [T[0]]> : Unwrapped<'ReadonlyTuple', ReadonlyTuple, Mutable<T>>;
27
+ type Mutable<T> = {
28
+ -readonly [K in keyof T]: T[K];
29
29
  };
30
- declare type _unwrap<T, From extends SearchList, R = {
31
- [K in keyof From as K extends ArrayKeys ? never : K extends string ? K : never]: From[K] extends Type ? Branch<T, From[K], K>[T extends Generic<From[K]> ? 'match' : 'miss'] : never;
32
- }> = R[keyof R];
33
- interface Branch<T, $T extends Type, K> {
34
- match: Disambiguate<T, $T, inferArgs<T, $T>, K & string>;
35
- miss: never;
36
- }
37
- declare type Disambiguate<T, $T extends Type, Args extends unknown[], K extends string> = Eq<T, apply<$T, Args>> extends true ? Unwrapped<K, $T, Args> : never;
30
+ type _unwrap<T, From> = {
31
+ [K in keyof From as K extends ArrayKeys ? never : K extends string ? K : never]: From[K] extends _Type ? T extends Generic<From[K]> ? Disambiguate<T, From[K], inferArgs<T, From[K]>, K & string> : never : never;
32
+ } extends infer R ? R[keyof R] : never;
33
+ type Disambiguate<T, $T extends _Type, Args extends unknown[], K extends string> = Eq<T, _apply<$T, Args>> extends true ? Unwrapped<K, $T, Args> : never;
38
34
  /** The result of unwrapping a type with `unwrap` */
39
- declare type Unwrapped<URI extends string = string, T extends Type = Type, A = unknown[]> = {
35
+ type Unwrapped<URI extends string = string, T extends _Type = Type, A = unknown[]> = {
40
36
  URI: URI;
41
37
  type: T;
42
38
  args: A;
@@ -44,4 +40,4 @@ declare type Unwrapped<URI extends string = string, T extends Type = Type, A = u
44
40
  interface $Any extends Type {
45
41
  type: any;
46
42
  }
47
- declare type Any = Unwrapped<'any', $Any, any>;
43
+ type Any = Unwrapped<'any', $Any, any>;
package/dist/utils.d.ts CHANGED
@@ -1,34 +1,69 @@
1
- export { Natural, Prev, Next, Subtract };
2
- export { ArrayKeys, Slice, ToTuple, Tuple, Head, Tail, Last, Init };
3
- export { Extends, Eq, And, Not, IsUnknown, IsAny, IsOptional };
4
- declare type Natural = [0, ..._Next];
5
- declare type Prev<I extends number> = number extends I ? number : number & _Prev[I];
6
- declare type _Prev = [never, ...Natural];
7
- declare type Next<I extends number> = number extends I ? number : number & _Next[I];
8
- declare type _Next = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64];
9
- declare type Subtract<A extends number, B extends number> = number extends A ? number : number extends B ? number : _Subtract<A, B>;
10
- declare type _Subtract<A extends number, B extends number, _A = Prev<A>, _B = Prev<B>> = B extends 0 ? A : [_A] extends [never] ? never : [_B] extends never ? never : _Subtract<_A & number, _B & number>;
11
- declare type ArrayKeys = Exclude<keyof [], never>;
12
- declare type Slice<T extends readonly unknown[], From extends number, To extends number = Required<T>['length'], I extends number = From, R extends unknown[] = []> = number extends To ? SliceOpenEndedTuple<T, From> : SliceTuple<T, From, To, I, R>;
13
- declare type SliceOpenEndedTuple<T extends readonly unknown[], From extends number> = From extends 0 ? T : T extends [unknown, ...infer R] ? SliceOpenEndedTuple<R, Prev<From>> : never;
14
- declare type SliceTuple<T extends readonly unknown[], From extends number, To extends number = Required<T>['length'], I extends number = From, R extends unknown[] = []> = I extends To ? R : Slice<T, From, To, Next<I>, IsOptional<T, I> extends true ? [...R, T[I]?] : [...R, T[I]]>;
15
- declare type IsOptional<T extends readonly unknown[], I extends number> = [
16
- {
17
- [K in T['length'] as K]: K extends I ? never : unknown;
18
- }[I]
19
- ] extends [never] ? true : false;
20
- declare type ToTuple<T extends readonly unknown[], I extends number = 0, R extends unknown[] = []> = any[] extends T ? T[0][] : I extends T['length'] ? R : ToTuple<T, Next<I>, [...R, T[I]]>;
21
- declare type Tuple<L extends number, T = unknown, R extends unknown[] = []> = number extends L ? T[] : L extends R['length'] ? R : Tuple<L, T, [T, ...R]>;
22
- declare type Head<T extends readonly [unknown, ...unknown[]]> = T[0];
23
- declare type Tail<T extends readonly [unknown, ...unknown[]]> = T extends [unknown, ...infer R] ? R : never;
24
- declare type Last<T extends readonly unknown[]> = T[Prev<T['length']>];
25
- declare type Init<T extends readonly [unknown, ...unknown[]]> = T extends [...infer R, unknown] ? R : never;
26
- declare type IsUnknown<T> = unknown extends T ? IsAny<T> extends false ? true : false : false;
27
- declare type IsAny<T> = Extends<T | anything, T & anything>;
28
- declare type Extends<A, B> = [A] extends [B] ? true : false;
29
- declare type Eq<A, B> = [A] extends [B] ? [B] extends [A] ? true : false : false;
30
- declare type And<A, B> = Fork<A, Fork<B, B, false>, false>;
31
- declare type Fork<P, T, F> = P extends false ? F : T;
32
- declare type Not<T> = Extends<T, false>;
1
+ export { Int, Cardinal as Natural, Prev, Next, Subtract };
2
+ type Int<T> = T extends `${infer I extends number}` ? I : T & number;
3
+ type Next<I> = number & _Next[I & number];
4
+ interface _Next extends Numeric, __Next {
5
+ }
6
+ type __Next = Omit<Natural, ArrayKeys>;
7
+ type Prev<I> = number & _Prev[I & number];
8
+ interface _Prev extends Numeric, __Prev {
9
+ }
10
+ type __Prev = Omit<[never, ...Cardinal], ArrayKeys>;
11
+ type Natural = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64];
12
+ type Cardinal = [0, ...Natural];
13
+ interface Numeric {
14
+ [k: number]: number;
15
+ }
16
+ type Subtract<A extends number, B extends number> = number extends A ? number : number extends B ? number : _Subtract<A, B>;
17
+ type _Subtract<A extends number, B extends number, _A = Prev<A>, _B = Prev<B>> = B extends 0 ? A : [_A] extends [never] ? never : [_B] extends never ? never : _Subtract<_A & number, _B & number>;
18
+ export { Mappable, OptionalKeys, ReverseMap };
19
+ type Mappable<T = unknown> = {
20
+ [k: PropertyKey]: T | undefined;
21
+ } | readonly (T | undefined)[];
22
+ type OptionalKeys<T> = {
23
+ [K in keyof T as K extends ArrayKeys ? number extends K ? never : K extends number ? K : never : K]-?: {} extends {
24
+ [P in K]: T[P];
25
+ } ? K : never;
26
+ } extends infer U ? U[keyof U] : never;
27
+ type ReverseMap<T extends {
28
+ [k: string]: any;
29
+ }> = {
30
+ [K in keyof T as T[K]]: K;
31
+ };
32
+ export { ArrayLike, Indexable, ArrayKeys, Slice, ToTuple, Tuple, NumericKeys, Head, Tail, Last, Init, IsOptional, GetRest };
33
+ type ArrayKeys = Exclude<keyof [], never>;
34
+ type ArrayLike = {
35
+ [k: number]: any;
36
+ length: any;
37
+ };
38
+ type Indexable = {
39
+ [k: number]: any;
40
+ };
41
+ type Slice<T extends Indexable, From extends number, To = T extends ArrayLike ? Required<T>['length'] : number, R extends any[] = [], Optional = Int<OptionalKeys<T>>> = number extends To ? SliceOpenEnded<T, From> : SliceOptional<T, From, To, R, Optional>;
42
+ type SliceOpenEnded<T extends Indexable, I> = I extends 0 ? T : T extends [unknown, ...infer R] ? SliceOpenEnded<R, Prev<I>> : never;
43
+ type SliceOptional<T extends Indexable, I, To, R extends any[], Optional> = I extends To ? R : SliceOptional<T, Next<I>, To, I extends Optional ? [...R, T[I & number]?] : [...R, T[I & number]], Optional>;
44
+ type IsOptional<T extends {
45
+ length: any;
46
+ }, I> = (T['length'] extends infer L ? L extends I ? true : false : never) extends false ? false : true;
47
+ type NumericKeys<T> = Int<ExcludeNumber<keyof T>>;
48
+ type ExcludeNumber<T> = T extends any ? number extends T ? never : T : never;
49
+ type ToTuple<T extends {
50
+ [k: number]: unknown;
51
+ length?: number;
52
+ }, Keys extends number = NumericKeys<T>, Optionals = Int<OptionalKeys<T>>, I extends number = 0, R extends unknown[] = []> = [Keys] extends [never] ? R : ToTuple<T, Exclude<Keys, I>, Optionals, Next<I>, I extends Optionals ? [...R, T[I]?] : [...R, T[I]]>;
53
+ type GetRest<T, U extends unknown[]> = T extends [...U, ...infer Rest] ? Rest : [];
54
+ type Tuple<L extends number, T = unknown, R extends any[] = number extends L ? T[] : []> = R['length'] extends L ? R : Tuple<L, T, [T, ...R]>;
55
+ type Head<T extends readonly unknown[]> = T[0];
56
+ type Tail<T extends readonly unknown[]> = T extends [unknown, ...infer R] ? R : never;
57
+ type Last<T extends readonly unknown[]> = T[Prev<T['length']>];
58
+ type Init<T extends readonly unknown[]> = T extends [...infer R, unknown] ? R : never;
59
+ export { Eq, IsUnknown, IsAny, UnknownToAny, PickUnionMember, Union2Tuple };
60
+ type IsUnknown<T> = unknown extends T ? IsAny<T> extends false ? true : false : false;
61
+ type IsAny<T> = [T | anything] extends [T & anything] ? true : false;
62
+ type UnknownToAny<T> = unknown extends T ? any : T;
63
+ type Eq<A, B> = [A] extends [B] ? [B] extends [A] ? true : false : false;
33
64
  declare const thing: unique symbol;
34
- declare type anything = typeof thing;
65
+ type anything = typeof thing;
66
+ type PickUnionMember<T, HOFs = T extends any ? (a: () => T) => void : never, Overloads = [HOFs] extends [(a: infer I) => any] ? I : never> = Overloads extends () => (infer R) ? R : never;
67
+ type Union2Tuple<U, T = PickUnionMember<U>> = [
68
+ U
69
+ ] extends [never] ? [] : [...Union2Tuple<Exclude<U, T>>, T];
package/dist/utils.js CHANGED
@@ -1 +1,2 @@
1
+ // Numbers
1
2
  export {};
package/package.json CHANGED
@@ -1,29 +1,34 @@
1
- {
2
- "name": "free-types-core",
3
- "version": "0.9.0",
4
- "description": "A type-level library enabling the creation and the manipulation of type constructors which are detached from their type parameters.",
5
- "keywords:": [
6
- "higher kinded type",
7
- "type constructor",
8
- "typescript"
9
- ],
10
- "main": "./dist/index.js",
11
- "types": "./dist/index.d.ts",
12
- "files": [
13
- "dist/*"
14
- ],
15
- "author": "Geoffrey Gourdet",
16
- "repository": {
17
- "type": "git",
18
- "url": "https://github.com/geoffreytools/free-types-core"
19
- },
20
- "license": "ICS",
21
- "devDependencies": {
22
- "typescript": "^4.7.2"
23
- },
24
- "scripts": {
25
- "build": "tsc",
26
- "watch": "tsc --watch",
27
- "trace": "tsc --generateTrace traceDir"
28
- }
29
- }
1
+ {
2
+ "name": "free-types-core",
3
+ "version": "1.0.1",
4
+ "description": "A type-level library enabling the creation and the manipulation of type constructors which are detached from their type parameters.",
5
+ "keywords:": [
6
+ "higher kinded type",
7
+ "type constructor",
8
+ "typescript"
9
+ ],
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "files": [
13
+ "dist/*"
14
+ ],
15
+ "author": "Geoffrey Gourdet",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/geoffreytools/free-types-core"
19
+ },
20
+ "license": "ICS",
21
+ "devDependencies": {
22
+ "foo": "github:geoffreytools/Foo",
23
+ "ts-spec": "^1.7.0",
24
+ "ts-trace": "github:geoffreytools/ts-trace",
25
+ "typescript": "^4.9.5"
26
+ },
27
+ "scripts": {
28
+ "watch build": "tsc -p ./tsconfig-build.json --watch",
29
+ "watch test": "tsc --watch",
30
+ "build": "tsc -p ./tsconfig-build.json",
31
+ "trace": "bash ./node_modules/ts-trace/ts-trace.sh -i ./tsconfig-perf.json",
32
+ "diagnostics": "tsc -p ./tsconfig-perf.json --extendedDiagnostics"
33
+ }
34
+ }
@@ -1,5 +0,0 @@
1
- import { Type } from './Type';
2
- import { Slice, Subtract } from './utils';
3
- export { Remaining };
4
- /** Use as a type constraint to match a Type whose state of application is known */
5
- declare type Remaining<T extends Type, R extends number> = unknown[] extends T['constraints'] ? Type : Type<Slice<T['constraints'], Subtract<T['constraints']['length'], R>, T['constraints']['length']>, T['type']>;
File without changes