utilium 2.7.2 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/array.d.ts +120 -0
- package/dist/array.js +1 -0
- package/dist/objects.d.ts +75 -5
- package/dist/objects.js +48 -7
- package/dist/string.d.ts +10 -1
- package/dist/type-math.d.ts +2 -1
- package/dist/type-math.test.js +3 -2
- package/dist/types.d.ts +2 -82
- package/package.json +1 -1
package/dist/array.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Subtract } from './type-math.js';
|
|
2
|
+
import type { Expand } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Filter an array by the types *not* assignable to `Predicate`
|
|
5
|
+
*
|
|
6
|
+
* @example ```ts
|
|
7
|
+
* type nonempty = FilterOut<['example', 'with', 'empty', ''], ''>; // ['example', 'with', 'empty']
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
export type FilterOut<Arr extends readonly any[], Predicate> = Arr extends readonly [infer Head, ...infer Rest] ? Head extends Predicate ? FilterOut<Rest, Predicate> : [Head, ...FilterOut<Rest, Predicate>] : [];
|
|
11
|
+
/**
|
|
12
|
+
* Filter an array by the types assignable to `Predicate`
|
|
13
|
+
*
|
|
14
|
+
* @example ```ts
|
|
15
|
+
* type negatives = Filter<['-1', '2', '-3'], `-${number}`>; // ['-1', '-3']
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export type Filter<Arr extends readonly any[], Predicate> = Arr extends readonly [infer Head, ...infer Rest] ? Head extends Predicate ? [Head, ...Filter<Rest, Predicate>] : Filter<Rest, Predicate> : [];
|
|
19
|
+
export type Some<Arr extends readonly any[], Predicate> = Arr extends readonly [infer Head, ...infer Rest] ? Head extends Predicate ? true : Some<Rest, Predicate> : false;
|
|
20
|
+
export type Every<Arr extends readonly any[], Predicate> = Arr extends readonly [infer Head, ...infer Rest] ? Head extends Predicate ? Every<Rest, Predicate> : false : true;
|
|
21
|
+
/**
|
|
22
|
+
* Empty
|
|
23
|
+
*/
|
|
24
|
+
export type Empty = [];
|
|
25
|
+
/**
|
|
26
|
+
* Removes the first element of T and shifts
|
|
27
|
+
*/
|
|
28
|
+
export type Shift<T extends unknown[]> = T extends [unknown, ...infer Rest] ? Rest : never;
|
|
29
|
+
/**
|
|
30
|
+
* Gets the first element of T
|
|
31
|
+
*/
|
|
32
|
+
export type First<T extends unknown[]> = T extends [infer F, ...unknown[]] ? F : never;
|
|
33
|
+
/**
|
|
34
|
+
* Inserts V into T at the start of T
|
|
35
|
+
*/
|
|
36
|
+
export type Unshift<T extends unknown[], V> = [V, ...T];
|
|
37
|
+
/**
|
|
38
|
+
* Removes the last element of T
|
|
39
|
+
*/
|
|
40
|
+
export type Pop<T extends unknown[]> = T extends [...infer _, unknown] ? _ : never;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the last element of T
|
|
43
|
+
*/
|
|
44
|
+
export type Last<T extends unknown[]> = T extends [...unknown[], infer Last] ? Last : never;
|
|
45
|
+
/**
|
|
46
|
+
* Appends V to T
|
|
47
|
+
*/
|
|
48
|
+
export type Push<T extends unknown[], V> = [...T, V];
|
|
49
|
+
/**
|
|
50
|
+
* Concatenates A and B
|
|
51
|
+
*/
|
|
52
|
+
export type Concat<A extends unknown[], B extends unknown[]> = Empty extends B ? A : Concat<Unshift<A, 0>, Shift<B>>;
|
|
53
|
+
/**
|
|
54
|
+
* Extracts from A what is not B
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* It does not remove duplicates (so Remove\<[0, 0, 0], [0, 0]\> yields [0]). This is intended and necessary behavior.
|
|
58
|
+
*/
|
|
59
|
+
export type Remove<A extends unknown[], B extends unknown[]> = Empty extends B ? A : Remove<Shift<A>, Shift<B>>;
|
|
60
|
+
/**
|
|
61
|
+
* The length of T
|
|
62
|
+
*/
|
|
63
|
+
export type Length<T extends unknown[]> = T extends {
|
|
64
|
+
length: infer L extends number;
|
|
65
|
+
} ? L : never;
|
|
66
|
+
type _FromLength<N extends number, R extends unknown[] = Empty> = Length<R> extends N ? R : _FromLength<N, Unshift<R, 0>>;
|
|
67
|
+
/**
|
|
68
|
+
* Creates a tuple of length N
|
|
69
|
+
*/
|
|
70
|
+
export type FromLength<N extends number> = _FromLength<N>;
|
|
71
|
+
/**
|
|
72
|
+
* Gets the type of an array's members
|
|
73
|
+
*/
|
|
74
|
+
export type Member<T, D = null> = D extends 0 ? T : T extends (infer U)[] ? Member<U, D extends number ? Subtract<D, 1> : null> : T;
|
|
75
|
+
/**
|
|
76
|
+
* Flattens an array
|
|
77
|
+
*/
|
|
78
|
+
export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[] ? Member<Exclude<U, A>, D>[] : A extends unknown[] ? {
|
|
79
|
+
[K in keyof A]: Member<A[K], D>;
|
|
80
|
+
} : A;
|
|
81
|
+
/**
|
|
82
|
+
* Whether T is a tuple
|
|
83
|
+
*/
|
|
84
|
+
export type IsTuple<T> = T extends [] ? false : T extends [infer _Head, ...infer _Rest] ? true : false;
|
|
85
|
+
/**
|
|
86
|
+
* Flattens a tuple
|
|
87
|
+
*/
|
|
88
|
+
export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest] ? U extends unknown[] ? [...U, ...FlattenTuple<Rest>] : [U, ...FlattenTuple<Rest>] : [];
|
|
89
|
+
/**
|
|
90
|
+
* Flattens an array or tuple
|
|
91
|
+
*/
|
|
92
|
+
export type Flatten<A extends unknown[]> = IsTuple<A> extends true ? FlattenTuple<A> : FlattenArray<A>;
|
|
93
|
+
type _Tuple<T, N extends number, R extends unknown[] = Empty> = R['length'] extends N ? R : _Tuple<T, N, [T, ...R]>;
|
|
94
|
+
/**
|
|
95
|
+
* Creates a tuple of T with length N
|
|
96
|
+
*/
|
|
97
|
+
export type Tuple<T, N extends number> = _Tuple<T, N>;
|
|
98
|
+
/**
|
|
99
|
+
* Makes all members of the tuple T optional
|
|
100
|
+
*/
|
|
101
|
+
export type OptionalTuple<T extends unknown[]> = T extends [infer Head, ...infer Tail] ? [Head?, ...OptionalTuple<Tail>] : T;
|
|
102
|
+
/**
|
|
103
|
+
* Converts an array of objects with a common key into a keyed object
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* type ducksArray = [
|
|
108
|
+
* { name: 'Gerald', quacks: 6 },
|
|
109
|
+
* { name: 'Dorthy', quacks: 7 },
|
|
110
|
+
* ];
|
|
111
|
+
*
|
|
112
|
+
* type ducks = FromKeyedArray<ducksArray, 'name'>; // { Gerald: { name: 'Gerald', quacks: 6 }, Dorthy: { name: 'Dorthy', quacks: 7 } }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export type FromKeyed<A extends any[], KeyName extends A extends (infer E)[] ? keyof E : never> = A extends (infer Element)[] ? {
|
|
116
|
+
[K in Element[KeyName] & PropertyKey]: Expand<Element & {
|
|
117
|
+
[_ in KeyName & PropertyKey]: K;
|
|
118
|
+
}>;
|
|
119
|
+
} : never;
|
|
120
|
+
export {};
|
package/dist/array.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/objects.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FilterOut } from './array.js';
|
|
2
|
+
import type { Split } from './string.js';
|
|
3
|
+
import type { $drain, Expand, UnionToTuple } from './types.js';
|
|
2
4
|
export declare function filterObject<O extends object, R extends object>(object: O, predicate: (key: keyof O, value: O[keyof O]) => boolean): R;
|
|
3
5
|
export declare function pick<T extends object, K extends keyof T>(object: T, ...keys: readonly K[]): Pick<T, K>;
|
|
4
6
|
export declare function pick<T extends object, K extends keyof T>(object: T, ...keys: readonly (readonly K[])[]): Pick<T, K>;
|
|
@@ -46,9 +48,77 @@ export interface ConstMap<T extends Partial<Record<keyof any, any>>, K extends k
|
|
|
46
48
|
has(key: keyof T | K): boolean;
|
|
47
49
|
}
|
|
48
50
|
export declare function map<const T extends Partial<Record<any, any>>>(items: T): Map<keyof T, T[keyof T]>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Flatten an object structure into a set of "keys".
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* type example = FlattenKeys<{ h: { s: { l: 1; v: 2 } } }>;
|
|
57
|
+
* type result = "h" | "h.s" | "h.s.l" | "h.s.v";
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export type FlattenKeys<O> = {
|
|
61
|
+
[K in keyof O & (string | number)]: O[K] extends Record<any, any> ? K | `${K}.${$drain<FlattenKeys<O[K]>>}` : K;
|
|
62
|
+
}[O extends readonly unknown[] ? keyof O & `${number}` : keyof O & (string | number)];
|
|
63
|
+
export type KeySeparator = '.' | '[' | ']';
|
|
64
|
+
type GetByPath<Data, Path extends (string | number)[]> = Path extends [
|
|
65
|
+
infer Key extends keyof Data | '__proto__',
|
|
66
|
+
...infer Rest extends (string | number)[]
|
|
67
|
+
] ? Key extends '__proto__' ? never : Rest extends [] ? Data[Key & keyof Data] : GetByPath<Data[Key & keyof Data], Rest> : undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Get a value using a path of property keys.
|
|
70
|
+
*
|
|
71
|
+
* @see {@link getByString}
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* interface Duck {
|
|
76
|
+
* taxonomy: {
|
|
77
|
+
* genus: 'anas';
|
|
78
|
+
* species: 'platyrhynchos';
|
|
79
|
+
* };
|
|
80
|
+
* }
|
|
81
|
+
*
|
|
82
|
+
* type DuckSpecies = GetByString<Duck, 'taxonomy.species'>; // 'platyrhynchos'
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export type GetByString<Data, Path extends string | number = FlattenKeys<Data>> = GetByPath<Data, FilterOut<Split<`${Path}`, KeySeparator>, ''>>;
|
|
86
|
+
/**
|
|
87
|
+
* Get a value using a path of property keys.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* Translation keys mapping to locale objects
|
|
91
|
+
* ```ts
|
|
92
|
+
* const locale = {
|
|
93
|
+
* preference: {
|
|
94
|
+
* theme: {
|
|
95
|
+
* label: 'Theme'
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
* } as const;
|
|
99
|
+
*
|
|
100
|
+
* const text = getByString(locale, 'preference.theme.label'); // 'Theme'
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* Arrays
|
|
105
|
+
* ```ts
|
|
106
|
+
* const pascal = {
|
|
107
|
+
* triangle: [
|
|
108
|
+
* [1],
|
|
109
|
+
* [1, 1],
|
|
110
|
+
* [1, 2, 1],
|
|
111
|
+
* [1, 3, 3, 1],
|
|
112
|
+
* [1, 4, 6, 4, 1]
|
|
113
|
+
* ]
|
|
114
|
+
* } as const;
|
|
115
|
+
*
|
|
116
|
+
* const row3 = getByString(pascal, 'triangle[3]'); // readonly [1, 3, 3, 1]
|
|
117
|
+
* const r4c3 = getByString(pascal, 'triangle[4][2]'); // 6
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare function getByString<const T, const P extends string | number = FlattenKeys<T>>(object: T, path: P): GetByString<T, P>;
|
|
121
|
+
export declare function setByString<const V, const T, const P extends string | number = FlattenKeys<T>>(object: T, path: P, value: V): V;
|
|
52
122
|
export type JSONPrimitive = null | string | number | boolean;
|
|
53
123
|
export interface JSONObject {
|
|
54
124
|
[K: string]: JSONValue | undefined;
|
|
@@ -149,4 +219,4 @@ export type Never<T> = {
|
|
|
149
219
|
* All of the properties in T or none of them
|
|
150
220
|
*/
|
|
151
221
|
export type AllOrNone<T> = T | Never<T>;
|
|
152
|
-
export
|
|
222
|
+
export {};
|
package/dist/objects.js
CHANGED
|
@@ -88,17 +88,58 @@ export function* getAllPrototypes(object) {
|
|
|
88
88
|
export function map(items) {
|
|
89
89
|
return new Map(Object.entries(items));
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
const keySeparator = /[.[\]]/;
|
|
92
|
+
/**
|
|
93
|
+
* Get a value using a path of property keys.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* Translation keys mapping to locale objects
|
|
97
|
+
* ```ts
|
|
98
|
+
* const locale = {
|
|
99
|
+
* preference: {
|
|
100
|
+
* theme: {
|
|
101
|
+
* label: 'Theme'
|
|
102
|
+
* }
|
|
103
|
+
* }
|
|
104
|
+
* } as const;
|
|
105
|
+
*
|
|
106
|
+
* const text = getByString(locale, 'preference.theme.label'); // 'Theme'
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* Arrays
|
|
111
|
+
* ```ts
|
|
112
|
+
* const pascal = {
|
|
113
|
+
* triangle: [
|
|
114
|
+
* [1],
|
|
115
|
+
* [1, 1],
|
|
116
|
+
* [1, 2, 1],
|
|
117
|
+
* [1, 3, 3, 1],
|
|
118
|
+
* [1, 4, 6, 4, 1]
|
|
119
|
+
* ]
|
|
120
|
+
* } as const;
|
|
121
|
+
*
|
|
122
|
+
* const row3 = getByString(pascal, 'triangle[3]'); // readonly [1, 3, 3, 1]
|
|
123
|
+
* const r4c3 = getByString(pascal, 'triangle[4][2]'); // 6
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export function getByString(object, path) {
|
|
92
127
|
return path
|
|
93
|
-
.
|
|
128
|
+
.toString()
|
|
129
|
+
.split(keySeparator)
|
|
94
130
|
.filter(p => p)
|
|
95
131
|
.reduce((o, p) => (p == '__proto__' ? _throw(new Error('getByString called with __proto__ in path')) : o?.[p]), object);
|
|
96
132
|
}
|
|
97
|
-
export function setByString(object, path, value
|
|
98
|
-
|
|
99
|
-
.
|
|
100
|
-
.
|
|
101
|
-
.
|
|
133
|
+
export function setByString(object, path, value) {
|
|
134
|
+
const parts = path
|
|
135
|
+
.toString()
|
|
136
|
+
.split(keySeparator)
|
|
137
|
+
.filter(p => p);
|
|
138
|
+
return parts.reduce((o, p, i) => {
|
|
139
|
+
if (p == '__proto__')
|
|
140
|
+
throw new Error('setByString called with __proto__ in path');
|
|
141
|
+
return (o[p] = parts.length === i + 1 ? value : o[p] || {});
|
|
142
|
+
}, object);
|
|
102
143
|
}
|
|
103
144
|
/**
|
|
104
145
|
* Binds a this value for all of the functions in an object (not recursive)
|
package/dist/string.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Some } from './array.js';
|
|
1
2
|
import type { $Max, w_subtract } from './type-math.js';
|
|
2
3
|
export declare function capitalize<T extends string>(value: T): Capitalize<T>;
|
|
3
4
|
export declare function uncapitalize<T extends string>(value: T): Uncapitalize<T>;
|
|
@@ -23,11 +24,19 @@ export declare function decodeUUID(uuid: Uint8Array): UUID;
|
|
|
23
24
|
export declare function encodeUUID(uuid: UUID): Uint8Array<ArrayBuffer>;
|
|
24
25
|
export declare function stringifyUUID(uuid: bigint): UUID;
|
|
25
26
|
export declare function parseUUID(uuid: UUID): bigint;
|
|
27
|
+
/**
|
|
28
|
+
* Used to support union delimiters, e.g. `'.' | ':'`
|
|
29
|
+
*/
|
|
30
|
+
type _SplitVariant<T extends string, CurrentDelim extends Delimiter, Delimiter extends string = ''> = T extends `${infer Left}${CurrentDelim}${infer Right}` ? [Left, ...Split<Right, Delimiter>] : [T];
|
|
26
31
|
/**
|
|
27
32
|
* Split a string.
|
|
28
33
|
*/
|
|
29
|
-
export type Split<T extends string, Delimiter extends string = ''> = string extends T ? string[] : T extends '' ? [] :
|
|
34
|
+
export type Split<T extends string, Delimiter extends string = ''> = string extends T ? string[] : T extends '' ? [''] : {
|
|
35
|
+
[D in Delimiter]: Some<_SplitVariant<T, D, Delimiter>, `${string}${Delimiter}${string}`> extends true ? never : _SplitVariant<T, D, Delimiter>;
|
|
36
|
+
}[Delimiter];
|
|
30
37
|
export type StringLength<T extends string> = Split<T>['length'];
|
|
31
38
|
export type Repeat<T extends string, N extends number, Init extends string = ''> = N extends 0 ? Init : Repeat<T, w_subtract<N, StringLength<T>>, `${Init}${T}`>;
|
|
32
39
|
export type PadRight<Init extends string, R extends string, N extends number> = Repeat<R, $Max<0, w_subtract<N, StringLength<Init>>>, Init>;
|
|
33
40
|
export type PadLeft<Init extends string, R extends string, N extends number> = `${Repeat<R, $Max<0, w_subtract<N, StringLength<Init>>>>}${Init}`;
|
|
41
|
+
export type NonEmptyString = `${any}${string}`;
|
|
42
|
+
export {};
|
package/dist/type-math.d.ts
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* `_*` => general purpose internals
|
|
12
12
|
*
|
|
13
13
|
*/
|
|
14
|
+
import type { Length } from './array.js';
|
|
14
15
|
import type { Repeat, StringLength } from './string.js';
|
|
15
|
-
import type { $drain
|
|
16
|
+
import type { $drain } from './types.js';
|
|
16
17
|
/**
|
|
17
18
|
* Maps a numeric literal type to a tuple type with that length
|
|
18
19
|
*/
|
package/dist/type-math.test.js
CHANGED
|
@@ -5,7 +5,7 @@ const add_positive = 3;
|
|
|
5
5
|
const add_zero = 0;
|
|
6
6
|
const add_diff_signs = -1;
|
|
7
7
|
const add_negative = -3;
|
|
8
|
-
const add_float = 1.
|
|
8
|
+
const add_float = 1.6;
|
|
9
9
|
// @ts-expect-error 2 + 2 != 5
|
|
10
10
|
let fail = 5;
|
|
11
11
|
fail = 4;
|
|
@@ -14,7 +14,7 @@ const subtract_normal = -18;
|
|
|
14
14
|
const subtract_from_neg = -9;
|
|
15
15
|
const subtract_both_neg = 5;
|
|
16
16
|
const subtract_zero = -1;
|
|
17
|
-
const subtract_floats = 3.
|
|
17
|
+
const subtract_floats = 3.1;
|
|
18
18
|
// were doing multiplication in the type system now?!
|
|
19
19
|
// yup.
|
|
20
20
|
const multiply_normal = 6;
|
|
@@ -34,5 +34,6 @@ const fraction_normal = 0.1415;
|
|
|
34
34
|
const fraction_negative = 0.1415;
|
|
35
35
|
// With type variable
|
|
36
36
|
const pi = 3.141;
|
|
37
|
+
// @ts-expect-error 2589 — Recently this started to become too deep even though it worked in the past
|
|
37
38
|
const octo_pi = 24.1128;
|
|
38
39
|
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Length, Unshift, Push, FromLength } from './array.js';
|
|
1
2
|
import type { Subtract } from './type-math.js';
|
|
2
3
|
/**
|
|
3
4
|
* Expands the type T (for intellisense and debugging)
|
|
@@ -23,97 +24,16 @@ type StrictUnionHelper<T, TAll> = T extends unknown ? T & Partial<Record<Exclude
|
|
|
23
24
|
* @see https://stackoverflow.com/a/65805753/17637456
|
|
24
25
|
*/
|
|
25
26
|
export type StrictUnion<T> = Expand<StrictUnionHelper<T, T>>;
|
|
26
|
-
/**
|
|
27
|
-
* Empty
|
|
28
|
-
*/
|
|
29
|
-
export type Empty = [];
|
|
30
|
-
/**
|
|
31
|
-
* Removes the first element of T and shifts
|
|
32
|
-
*/
|
|
33
|
-
export type Shift<T extends unknown[]> = T extends [unknown, ...infer Rest] ? Rest : never;
|
|
34
|
-
/**
|
|
35
|
-
* Gets the first element of T
|
|
36
|
-
*/
|
|
37
|
-
export type First<T extends unknown[]> = T extends [infer F, ...unknown[]] ? F : never;
|
|
38
|
-
/**
|
|
39
|
-
* Inserts V into T at the start of T
|
|
40
|
-
*/
|
|
41
|
-
export type Unshift<T extends unknown[], V> = [V, ...T];
|
|
42
|
-
/**
|
|
43
|
-
* Removes the last element of T
|
|
44
|
-
*/
|
|
45
|
-
export type Pop<T extends unknown[]> = T extends [...infer _, unknown] ? _ : never;
|
|
46
|
-
/**
|
|
47
|
-
* Gets the last element of T
|
|
48
|
-
*/
|
|
49
|
-
export type Last<T extends unknown[]> = T extends [...unknown[], infer Last] ? Last : never;
|
|
50
|
-
/**
|
|
51
|
-
* Appends V to T
|
|
52
|
-
*/
|
|
53
|
-
export type Push<T extends unknown[], V> = [...T, V];
|
|
54
|
-
/**
|
|
55
|
-
* Concats A and B
|
|
56
|
-
*/
|
|
57
|
-
export type Concat<A extends unknown[], B extends unknown[]> = Empty extends B ? A : Concat<Unshift<A, 0>, Shift<B>>;
|
|
58
|
-
/**
|
|
59
|
-
* Extracts from A what is not B
|
|
60
|
-
*
|
|
61
|
-
* @remarks
|
|
62
|
-
* It does not remove duplicates (so Remove\<[0, 0, 0], [0, 0]\> yields [0]). This is intended and necessary behavior.
|
|
63
|
-
*/
|
|
64
|
-
export type Remove<A extends unknown[], B extends unknown[]> = Empty extends B ? A : Remove<Shift<A>, Shift<B>>;
|
|
65
|
-
/**
|
|
66
|
-
* The length of T
|
|
67
|
-
*/
|
|
68
|
-
export type Length<T extends unknown[]> = T extends {
|
|
69
|
-
length: infer L extends number;
|
|
70
|
-
} ? L : never;
|
|
71
|
-
type _FromLength<N extends number, R extends unknown[] = Empty> = Length<R> extends N ? R : _FromLength<N, Unshift<R, 0>>;
|
|
72
|
-
/**
|
|
73
|
-
* Creates a tuple of length N
|
|
74
|
-
*/
|
|
75
|
-
export type FromLength<N extends number> = _FromLength<N>;
|
|
76
27
|
/**
|
|
77
28
|
* Increments N
|
|
78
29
|
* @deprecated Use Add<N, 1> instead
|
|
79
30
|
*/
|
|
80
|
-
export type Increment<N extends number> = Length<Unshift<
|
|
31
|
+
export type Increment<N extends number> = Length<Unshift<FromLength<N>, 0>>;
|
|
81
32
|
/**
|
|
82
33
|
* Decrements N
|
|
83
34
|
* @deprecated Use Subtract<N, 1> instead
|
|
84
35
|
*/
|
|
85
36
|
export type Decrement<N extends number> = Subtract<N, 1>;
|
|
86
|
-
/**
|
|
87
|
-
* Gets the type of an array's members
|
|
88
|
-
*/
|
|
89
|
-
export type Member<T, D = null> = D extends 0 ? T : T extends (infer U)[] ? Member<U, D extends number ? Subtract<D, 1> : null> : T;
|
|
90
|
-
/**
|
|
91
|
-
* Flattens an array
|
|
92
|
-
*/
|
|
93
|
-
export type FlattenArray<A extends unknown[], D = null> = A extends (infer U)[] ? Member<Exclude<U, A>, D>[] : A extends unknown[] ? {
|
|
94
|
-
[K in keyof A]: Member<A[K], D>;
|
|
95
|
-
} : A;
|
|
96
|
-
/**
|
|
97
|
-
* Whether T is a tuple
|
|
98
|
-
*/
|
|
99
|
-
export type IsTuple<T> = T extends [] ? false : T extends [infer _Head, ...infer _Rest] ? true : false;
|
|
100
|
-
/**
|
|
101
|
-
* Flattens a tuple
|
|
102
|
-
*/
|
|
103
|
-
export type FlattenTuple<A extends unknown[]> = A extends [infer U, ...infer Rest] ? U extends unknown[] ? [...U, ...FlattenTuple<Rest>] : [U, ...FlattenTuple<Rest>] : [];
|
|
104
|
-
/**
|
|
105
|
-
* Flattens an array or tuple
|
|
106
|
-
*/
|
|
107
|
-
export type Flatten<A extends unknown[]> = IsTuple<A> extends true ? FlattenTuple<A> : FlattenArray<A>;
|
|
108
|
-
type _Tuple<T, N extends number, R extends unknown[] = Empty> = R['length'] extends N ? R : _Tuple<T, N, [T, ...R]>;
|
|
109
|
-
/**
|
|
110
|
-
* Creates a tuple of T with length N
|
|
111
|
-
*/
|
|
112
|
-
export type Tuple<T, N extends number> = _Tuple<T, N>;
|
|
113
|
-
/**
|
|
114
|
-
* Makes all members of the tuple T optional
|
|
115
|
-
*/
|
|
116
|
-
export type OptionalTuple<T extends unknown[]> = T extends [infer Head, ...infer Tail] ? [Head?, ...OptionalTuple<Tail>] : T;
|
|
117
37
|
/**
|
|
118
38
|
* Keys of a Map
|
|
119
39
|
*/
|