@esposter/shared 2.1.0 → 2.2.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.
- package/README.md +17 -0
- package/dist/index.d.ts +171 -222
- package/package.json +5 -2
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @esposter/shared
|
|
2
|
+
|
|
3
|
+
[![Apache-2.0 licensed][badge-license]][url-license]
|
|
4
|
+
[![NPM version][badge-npm-version]][url-npm]
|
|
5
|
+
[![NPM downloads][badge-npm-downloads]][url-npm]
|
|
6
|
+
[![NPM Unpacked Size (with version)][badge-npm-unpacked-size]][url-npm]
|
|
7
|
+
|
|
8
|
+
## <a name="license">⚖️ License</a>
|
|
9
|
+
|
|
10
|
+
This project is licensed under the [Apache-2.0 license](https://github.com/Esposter/Esposter/blob/main/LICENSE).
|
|
11
|
+
|
|
12
|
+
[badge-license]: https://img.shields.io/github/license/Esposter/Esposter.svg?color=blue
|
|
13
|
+
[url-license]: https://github.com/Esposter/Esposter/blob/main/LICENSE
|
|
14
|
+
[badge-npm-version]: https://img.shields.io/npm/v/@esposter/shared/latest?color=brightgreen
|
|
15
|
+
[url-npm]: https://www.npmjs.com/package/@esposter/shared/v/latest
|
|
16
|
+
[badge-npm-unpacked-size]: https://img.shields.io/npm/unpacked-size/@esposter/shared/latest?label=npm
|
|
17
|
+
[badge-npm-downloads]: https://img.shields.io/npm/dm/@esposter/shared.svg
|
package/dist/index.d.ts
CHANGED
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
//#region src/models/shared/Operation.d.ts
|
|
2
2
|
declare enum Operation {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
//#endregion
|
|
3
|
+
Create = "Create",
|
|
4
|
+
Delete = "Delete",
|
|
5
|
+
Push = "Push",
|
|
6
|
+
Read = "Read",
|
|
7
|
+
Update = "Update",
|
|
8
|
+
} //#endregion
|
|
11
9
|
//#region src/models/error/InvalidOperationError.d.ts
|
|
12
10
|
declare class InvalidOperationError extends Error {
|
|
13
|
-
|
|
11
|
+
constructor(operation: Operation, name: string, message: string);
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
//#endregion
|
|
17
15
|
//#region src/models/error/NotFoundError.d.ts
|
|
18
16
|
declare class NotFoundError<T extends string = string> extends Error {
|
|
19
|
-
|
|
17
|
+
constructor(name: T, id: string);
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
//#endregion
|
|
23
21
|
//#region src/models/error/NotInitializedError.d.ts
|
|
24
22
|
declare class NotInitializedError<T extends string = string> extends Error {
|
|
25
|
-
|
|
23
|
+
constructor(name: T);
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
//#endregion
|
|
@@ -35,7 +33,7 @@ declare const isPlainObject: (data: unknown) => data is object;
|
|
|
35
33
|
|
|
36
34
|
//#endregion
|
|
37
35
|
//#region src/util/types/MergeObjectsStrict.d.ts
|
|
38
|
-
type MergeObjectsStrict<T extends object[]> = T extends [infer TFirst, infer TSecond, ...infer TRemaining] ? TSecond extends { [K in keyof TSecond]
|
|
36
|
+
type MergeObjectsStrict<T extends object[]> = T extends [infer TFirst, infer TSecond, ...infer TRemaining] ? TSecond extends { [K in keyof TSecond]: K extends keyof TFirst ? never : TSecond[K] } ? TRemaining extends object[] ? MergeObjectsStrict<[TSecond, ...TRemaining]> & TFirst : TFirst & TSecond : never : T extends [infer TFirst] ? TFirst : never;
|
|
39
37
|
|
|
40
38
|
//#endregion
|
|
41
39
|
//#region src/util/object/mergeObjectsStrict.d.ts
|
|
@@ -55,19 +53,30 @@ declare const toKebabCase: <T extends string>(string: T) => CamelToKebab<T>;
|
|
|
55
53
|
|
|
56
54
|
//#endregion
|
|
57
55
|
//#region src/util/types/FunctionProperties.d.ts
|
|
58
|
-
type FunctionProperties<T> = { [K in keyof T]
|
|
56
|
+
type FunctionProperties<T> = { [K in keyof T]: T[K] extends Function ? K : never };
|
|
59
57
|
|
|
60
58
|
//#endregion
|
|
61
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
59
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/observable-like.d.ts
|
|
62
60
|
declare global {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
|
|
62
|
+
interface SymbolConstructor {
|
|
63
|
+
readonly observable: symbol;
|
|
64
|
+
}
|
|
67
65
|
}
|
|
68
66
|
|
|
69
67
|
//#endregion
|
|
70
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
68
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/optional-keys-of.d.ts
|
|
69
|
+
/**
|
|
70
|
+
@remarks
|
|
71
|
+
The TC39 observable proposal defines a `closed` property, but some implementations (such as xstream) do not as of 10/08/2021.
|
|
72
|
+
As well, some guidance on making an `Observable` to not include `closed` property.
|
|
73
|
+
@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130
|
|
74
|
+
@see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85
|
|
75
|
+
@see https://github.com/benlesh/symbol-observable#making-an-object-observable
|
|
76
|
+
|
|
77
|
+
@category Observable
|
|
78
|
+
*/
|
|
79
|
+
|
|
71
80
|
/**
|
|
72
81
|
Extract all optional keys from the given type.
|
|
73
82
|
|
|
@@ -78,38 +87,36 @@ This is useful when you want to create a new type that contains different type v
|
|
|
78
87
|
import type {OptionalKeysOf, Except} from 'type-fest';
|
|
79
88
|
|
|
80
89
|
interface User {
|
|
81
|
-
name: string;
|
|
82
|
-
surname: string;
|
|
90
|
+
name: string;
|
|
91
|
+
surname: string;
|
|
83
92
|
|
|
84
|
-
luckyNumber?: number;
|
|
93
|
+
luckyNumber?: number;
|
|
85
94
|
}
|
|
86
95
|
|
|
87
96
|
const REMOVE_FIELD = Symbol('remove field symbol');
|
|
88
97
|
type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
|
|
89
|
-
[Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
|
|
98
|
+
[Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD;
|
|
90
99
|
};
|
|
91
100
|
|
|
92
101
|
const update1: UpdateOperation<User> = {
|
|
93
|
-
name: 'Alice'
|
|
102
|
+
name: 'Alice'
|
|
94
103
|
};
|
|
95
104
|
|
|
96
105
|
const update2: UpdateOperation<User> = {
|
|
97
|
-
name: 'Bob',
|
|
98
|
-
luckyNumber: REMOVE_FIELD
|
|
106
|
+
name: 'Bob',
|
|
107
|
+
luckyNumber: REMOVE_FIELD
|
|
99
108
|
};
|
|
100
109
|
```
|
|
101
110
|
|
|
102
111
|
@category Utilities
|
|
103
112
|
*/
|
|
104
|
-
type OptionalKeysOf<BaseType extends object> =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
[Key in keyof BaseType as BaseType extends Record<Key, BaseType[Key]> ? never : Key]: never
|
|
108
|
-
}) & (keyof BaseType) // Intersect with `keyof BaseType` to ensure result of `OptionalKeysOf<BaseType>` is always assignable to `keyof BaseType`
|
|
109
|
-
: never;
|
|
113
|
+
type OptionalKeysOf<BaseType extends object> = BaseType extends unknown // For distributing `BaseType`
|
|
114
|
+
? (keyof { [Key in keyof BaseType as BaseType extends Record<Key, BaseType[Key]> ? never : Key]: never }) & (keyof BaseType) // Intersect with `keyof BaseType` to ensure result of `OptionalKeysOf<BaseType>` is always assignable to `keyof BaseType`
|
|
115
|
+
: never;
|
|
110
116
|
|
|
111
117
|
//#endregion
|
|
112
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
118
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/required-keys-of.d.ts
|
|
119
|
+
// Should never happen
|
|
113
120
|
/**
|
|
114
121
|
Extract all required keys from the given type.
|
|
115
122
|
|
|
@@ -122,10 +129,10 @@ import type {RequiredKeysOf} from 'type-fest';
|
|
|
122
129
|
declare function createValidation<Entity extends object, Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>>(field: Key, validator: (value: Entity[Key]) => boolean): ValidatorFn;
|
|
123
130
|
|
|
124
131
|
interface User {
|
|
125
|
-
name: string;
|
|
126
|
-
surname: string;
|
|
132
|
+
name: string;
|
|
133
|
+
surname: string;
|
|
127
134
|
|
|
128
|
-
luckyNumber?: number;
|
|
135
|
+
luckyNumber?: number;
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
const validator1 = createValidation<User>('name', value => value.length < 25);
|
|
@@ -134,13 +141,13 @@ const validator2 = createValidation<User>('surname', value => value.length < 25)
|
|
|
134
141
|
|
|
135
142
|
@category Utilities
|
|
136
143
|
*/
|
|
137
|
-
type RequiredKeysOf<BaseType extends object> =
|
|
138
|
-
|
|
139
|
-
? Exclude<keyof BaseType, OptionalKeysOf<BaseType>>
|
|
140
|
-
: never;
|
|
144
|
+
type RequiredKeysOf<BaseType extends object> = BaseType extends unknown // For distributing `BaseType`
|
|
145
|
+
? Exclude<keyof BaseType, OptionalKeysOf<BaseType>> : never;
|
|
141
146
|
|
|
142
147
|
//#endregion
|
|
143
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
148
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/is-never.d.ts
|
|
149
|
+
// Should never happen
|
|
150
|
+
|
|
144
151
|
/**
|
|
145
152
|
Returns a boolean for whether the given type is `never`.
|
|
146
153
|
|
|
@@ -156,20 +163,20 @@ import type {IsNever, And} from 'type-fest';
|
|
|
156
163
|
|
|
157
164
|
// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
|
|
158
165
|
type AreStringsEqual<A extends string, B extends string> =
|
|
159
|
-
And<
|
|
160
|
-
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
161
|
-
IsNever<Exclude<B, A>> extends true ? true : false
|
|
162
|
-
>;
|
|
166
|
+
And<
|
|
167
|
+
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
168
|
+
IsNever<Exclude<B, A>> extends true ? true : false
|
|
169
|
+
>;
|
|
163
170
|
|
|
164
171
|
type EndIfEqual<I extends string, O extends string> =
|
|
165
|
-
AreStringsEqual<I, O> extends true
|
|
166
|
-
? never
|
|
167
|
-
: void;
|
|
172
|
+
AreStringsEqual<I, O> extends true
|
|
173
|
+
? never
|
|
174
|
+
: void;
|
|
168
175
|
|
|
169
176
|
function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
|
|
170
|
-
if (input === output) {
|
|
171
|
-
process.exit(0);
|
|
172
|
-
}
|
|
177
|
+
if (input === output) {
|
|
178
|
+
process.exit(0);
|
|
179
|
+
}
|
|
173
180
|
}
|
|
174
181
|
|
|
175
182
|
endIfEqual('abc', 'abc');
|
|
@@ -185,7 +192,7 @@ endIfEqual('abc', '123');
|
|
|
185
192
|
type IsNever<T> = [T] extends [never] ? true : false;
|
|
186
193
|
|
|
187
194
|
//#endregion
|
|
188
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
195
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/if-never.d.ts
|
|
189
196
|
/**
|
|
190
197
|
An if-else-like type that resolves depending on whether the given type is `never`.
|
|
191
198
|
|
|
@@ -205,13 +212,14 @@ type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
|
|
|
205
212
|
@category Type Guard
|
|
206
213
|
@category Utilities
|
|
207
214
|
*/
|
|
208
|
-
type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
|
|
209
|
-
IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
|
|
210
|
-
);
|
|
215
|
+
type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (IsNever<T> extends true ? TypeIfNever : TypeIfNotNever);
|
|
211
216
|
|
|
212
217
|
//#endregion
|
|
213
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
218
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/is-any.d.ts
|
|
219
|
+
// Can eventually be replaced with the built-in once this library supports
|
|
220
|
+
// TS5.4+ only. Tracked in https://github.com/sindresorhus/type-fest/issues/848
|
|
214
221
|
type NoInfer<T> = T extends infer U ? U : never;
|
|
222
|
+
|
|
215
223
|
/**
|
|
216
224
|
Returns a boolean for whether the given type is `any`.
|
|
217
225
|
|
|
@@ -227,7 +235,7 @@ const typedObject = {a: 1, b: 2} as const;
|
|
|
227
235
|
const anyObject: any = {a: 1, b: 2};
|
|
228
236
|
|
|
229
237
|
function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {
|
|
230
|
-
return obj[key];
|
|
238
|
+
return obj[key];
|
|
231
239
|
}
|
|
232
240
|
|
|
233
241
|
const typedA = get(typedObject, 'a');
|
|
@@ -243,7 +251,7 @@ const anyA = get(anyObject, 'a');
|
|
|
243
251
|
type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
|
|
244
252
|
|
|
245
253
|
//#endregion
|
|
246
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
254
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/is-equal.d.ts
|
|
247
255
|
/**
|
|
248
256
|
Returns a boolean for whether the two given types are equal.
|
|
249
257
|
|
|
@@ -260,24 +268,20 @@ import type {IsEqual} from 'type-fest';
|
|
|
260
268
|
// This type returns a boolean for whether the given array includes the given item.
|
|
261
269
|
// `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal.
|
|
262
270
|
type Includes<Value extends readonly any[], Item> =
|
|
263
|
-
Value extends readonly [Value[0], ...infer rest]
|
|
264
|
-
? IsEqual<Value[0], Item> extends true
|
|
265
|
-
? true
|
|
266
|
-
: Includes<rest, Item>
|
|
267
|
-
: false;
|
|
271
|
+
Value extends readonly [Value[0], ...infer rest]
|
|
272
|
+
? IsEqual<Value[0], Item> extends true
|
|
273
|
+
? true
|
|
274
|
+
: Includes<rest, Item>
|
|
275
|
+
: false;
|
|
268
276
|
```
|
|
269
277
|
|
|
270
278
|
@category Type Guard
|
|
271
279
|
@category Utilities
|
|
272
280
|
*/
|
|
273
|
-
type IsEqual<A, B> =
|
|
274
|
-
(<G>() => G extends A & G | G ? 1 : 2) extends
|
|
275
|
-
(<G>() => G extends B & G | G ? 1 : 2)
|
|
276
|
-
? true
|
|
277
|
-
: false;
|
|
281
|
+
type IsEqual<A, B> = (<G>() => G extends A & G | G ? 1 : 2) extends (<G>() => G extends B & G | G ? 1 : 2) ? true : false;
|
|
278
282
|
|
|
279
283
|
//#endregion
|
|
280
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
284
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/simplify.d.ts
|
|
281
285
|
/**
|
|
282
286
|
Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
|
|
283
287
|
|
|
@@ -286,13 +290,13 @@ Useful to flatten the type output to improve type hints shown in editors. And al
|
|
|
286
290
|
import type {Simplify} from 'type-fest';
|
|
287
291
|
|
|
288
292
|
type PositionProps = {
|
|
289
|
-
top: number;
|
|
290
|
-
left: number;
|
|
293
|
+
top: number;
|
|
294
|
+
left: number;
|
|
291
295
|
};
|
|
292
296
|
|
|
293
297
|
type SizeProps = {
|
|
294
|
-
width: number;
|
|
295
|
-
height: number;
|
|
298
|
+
width: number;
|
|
299
|
+
height: number;
|
|
296
300
|
};
|
|
297
301
|
|
|
298
302
|
// In your editor, hovering over `Props` will show a flattened object with all the properties.
|
|
@@ -308,15 +312,15 @@ If the type definition must be an interface (perhaps it was defined in a third-p
|
|
|
308
312
|
import type {Simplify} from 'type-fest';
|
|
309
313
|
|
|
310
314
|
interface SomeInterface {
|
|
311
|
-
foo: number;
|
|
312
|
-
bar?: string;
|
|
313
|
-
baz: number | undefined;
|
|
315
|
+
foo: number;
|
|
316
|
+
bar?: string;
|
|
317
|
+
baz: number | undefined;
|
|
314
318
|
}
|
|
315
319
|
|
|
316
320
|
type SomeType = {
|
|
317
|
-
foo: number;
|
|
318
|
-
bar?: string;
|
|
319
|
-
baz: number | undefined;
|
|
321
|
+
foo: number;
|
|
322
|
+
bar?: string;
|
|
323
|
+
baz: number | undefined;
|
|
320
324
|
};
|
|
321
325
|
|
|
322
326
|
const literal = {foo: 123, bar: 'hello', baz: 456};
|
|
@@ -335,10 +339,10 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
|
|
|
335
339
|
@see SimplifyDeep
|
|
336
340
|
@category Object
|
|
337
341
|
*/
|
|
338
|
-
type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
|
|
342
|
+
type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
|
|
339
343
|
|
|
340
344
|
//#endregion
|
|
341
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
345
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/omit-index-signature.d.ts
|
|
342
346
|
/**
|
|
343
347
|
Omit any index signatures from the given object type, leaving only explicitly defined properties.
|
|
344
348
|
|
|
@@ -364,13 +368,13 @@ Instead of causing a type error like the above, you can also use a [conditional
|
|
|
364
368
|
|
|
365
369
|
```
|
|
366
370
|
type Indexed = {} extends Record<string, unknown>
|
|
367
|
-
? '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
368
|
-
: '❌ `{}` is NOT assignable to `Record<string, unknown>`';
|
|
371
|
+
? '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
372
|
+
: '❌ `{}` is NOT assignable to `Record<string, unknown>`';
|
|
369
373
|
// => '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
370
374
|
|
|
371
375
|
type Keyed = {} extends Record<'foo' | 'bar', unknown>
|
|
372
|
-
? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`"
|
|
373
|
-
: "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";
|
|
376
|
+
? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`"
|
|
377
|
+
: "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`";
|
|
374
378
|
// => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"
|
|
375
379
|
```
|
|
376
380
|
|
|
@@ -380,8 +384,8 @@ Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-type
|
|
|
380
384
|
import type {OmitIndexSignature} from 'type-fest';
|
|
381
385
|
|
|
382
386
|
type OmitIndexSignature<ObjectType> = {
|
|
383
|
-
[KeyType in keyof ObjectType // Map each key of `ObjectType`...
|
|
384
|
-
]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.
|
|
387
|
+
[KeyType in keyof ObjectType // Map each key of `ObjectType`...
|
|
388
|
+
]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.
|
|
385
389
|
};
|
|
386
390
|
```
|
|
387
391
|
|
|
@@ -391,12 +395,12 @@ type OmitIndexSignature<ObjectType> = {
|
|
|
391
395
|
import type {OmitIndexSignature} from 'type-fest';
|
|
392
396
|
|
|
393
397
|
type OmitIndexSignature<ObjectType> = {
|
|
394
|
-
[KeyType in keyof ObjectType
|
|
395
|
-
// Is `{}` assignable to `Record<KeyType, unknown>`?
|
|
396
|
-
as {} extends Record<KeyType, unknown>
|
|
397
|
-
? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`
|
|
398
|
-
: ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
|
|
399
|
-
]: ObjectType[KeyType];
|
|
398
|
+
[KeyType in keyof ObjectType
|
|
399
|
+
// Is `{}` assignable to `Record<KeyType, unknown>`?
|
|
400
|
+
as {} extends Record<KeyType, unknown>
|
|
401
|
+
? ... // ✅ `{}` is assignable to `Record<KeyType, unknown>`
|
|
402
|
+
: ... // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
|
|
403
|
+
]: ObjectType[KeyType];
|
|
400
404
|
};
|
|
401
405
|
```
|
|
402
406
|
|
|
@@ -407,19 +411,19 @@ If `{}` is assignable, it means that `KeyType` is an index signature and we want
|
|
|
407
411
|
import type {OmitIndexSignature} from 'type-fest';
|
|
408
412
|
|
|
409
413
|
interface Example {
|
|
410
|
-
// These index signatures will be removed.
|
|
411
|
-
[x: string]: any
|
|
412
|
-
[x: number]: any
|
|
413
|
-
[x: symbol]: any
|
|
414
|
-
[x: `head-${string}`]: string
|
|
415
|
-
[x: `${string}-tail`]: string
|
|
416
|
-
[x: `head-${string}-tail`]: string
|
|
417
|
-
[x: `${bigint}`]: string
|
|
418
|
-
[x: `embedded-${number}`]: string
|
|
419
|
-
|
|
420
|
-
// These explicitly defined keys will remain.
|
|
421
|
-
foo: 'bar';
|
|
422
|
-
qux?: 'baz';
|
|
414
|
+
// These index signatures will be removed.
|
|
415
|
+
[x: string]: any
|
|
416
|
+
[x: number]: any
|
|
417
|
+
[x: symbol]: any
|
|
418
|
+
[x: `head-${string}`]: string
|
|
419
|
+
[x: `${string}-tail`]: string
|
|
420
|
+
[x: `head-${string}-tail`]: string
|
|
421
|
+
[x: `${bigint}`]: string
|
|
422
|
+
[x: `embedded-${number}`]: string
|
|
423
|
+
|
|
424
|
+
// These explicitly defined keys will remain.
|
|
425
|
+
foo: 'bar';
|
|
426
|
+
qux?: 'baz';
|
|
423
427
|
}
|
|
424
428
|
|
|
425
429
|
type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
|
|
@@ -429,14 +433,10 @@ type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
|
|
|
429
433
|
@see PickIndexSignature
|
|
430
434
|
@category Object
|
|
431
435
|
*/
|
|
432
|
-
type OmitIndexSignature<ObjectType> = {
|
|
433
|
-
[KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
|
|
434
|
-
? never
|
|
435
|
-
: KeyType]: ObjectType[KeyType];
|
|
436
|
-
};
|
|
436
|
+
type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType] };
|
|
437
437
|
|
|
438
438
|
//#endregion
|
|
439
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
439
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/pick-index-signature.d.ts
|
|
440
440
|
/**
|
|
441
441
|
Pick only index signatures from the given object type, leaving out all explicitly defined properties.
|
|
442
442
|
|
|
@@ -449,21 +449,21 @@ import type {PickIndexSignature} from 'type-fest';
|
|
|
449
449
|
declare const symbolKey: unique symbol;
|
|
450
450
|
|
|
451
451
|
type Example = {
|
|
452
|
-
// These index signatures will remain.
|
|
453
|
-
[x: string]: unknown;
|
|
454
|
-
[x: number]: unknown;
|
|
455
|
-
[x: symbol]: unknown;
|
|
456
|
-
[x: `head-${string}`]: string;
|
|
457
|
-
[x: `${string}-tail`]: string;
|
|
458
|
-
[x: `head-${string}-tail`]: string;
|
|
459
|
-
[x: `${bigint}`]: string;
|
|
460
|
-
[x: `embedded-${number}`]: string;
|
|
461
|
-
|
|
462
|
-
// These explicitly defined keys will be removed.
|
|
463
|
-
['kebab-case-key']: string;
|
|
464
|
-
[symbolKey]: string;
|
|
465
|
-
foo: 'bar';
|
|
466
|
-
qux?: 'baz';
|
|
452
|
+
// These index signatures will remain.
|
|
453
|
+
[x: string]: unknown;
|
|
454
|
+
[x: number]: unknown;
|
|
455
|
+
[x: symbol]: unknown;
|
|
456
|
+
[x: `head-${string}`]: string;
|
|
457
|
+
[x: `${string}-tail`]: string;
|
|
458
|
+
[x: `head-${string}-tail`]: string;
|
|
459
|
+
[x: `${bigint}`]: string;
|
|
460
|
+
[x: `embedded-${number}`]: string;
|
|
461
|
+
|
|
462
|
+
// These explicitly defined keys will be removed.
|
|
463
|
+
['kebab-case-key']: string;
|
|
464
|
+
[symbolKey]: string;
|
|
465
|
+
foo: 'bar';
|
|
466
|
+
qux?: 'baz';
|
|
467
467
|
};
|
|
468
468
|
|
|
469
469
|
type ExampleIndexSignature = PickIndexSignature<Example>;
|
|
@@ -482,17 +482,13 @@ type ExampleIndexSignature = PickIndexSignature<Example>;
|
|
|
482
482
|
@see OmitIndexSignature
|
|
483
483
|
@category Object
|
|
484
484
|
*/
|
|
485
|
-
type PickIndexSignature<ObjectType> = {
|
|
486
|
-
[KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
|
|
487
|
-
? KeyType
|
|
488
|
-
: never]: ObjectType[KeyType];
|
|
489
|
-
};
|
|
485
|
+
type PickIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType] };
|
|
490
486
|
|
|
491
487
|
//#endregion
|
|
492
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
488
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/merge.d.ts
|
|
489
|
+
// Merges two objects without worrying about index signatures.
|
|
490
|
+
type SimpleMerge<Destination, Source> = { [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key] } & Source;
|
|
491
|
+
|
|
496
492
|
/**
|
|
497
493
|
Merge two types into a new type. Keys of the second type overrides keys of the first type.
|
|
498
494
|
|
|
@@ -501,17 +497,17 @@ Merge two types into a new type. Keys of the second type overrides keys of the f
|
|
|
501
497
|
import type {Merge} from 'type-fest';
|
|
502
498
|
|
|
503
499
|
interface Foo {
|
|
504
|
-
[x: string]: unknown;
|
|
505
|
-
[x: number]: unknown;
|
|
506
|
-
foo: string;
|
|
507
|
-
bar: symbol;
|
|
500
|
+
[x: string]: unknown;
|
|
501
|
+
[x: number]: unknown;
|
|
502
|
+
foo: string;
|
|
503
|
+
bar: symbol;
|
|
508
504
|
}
|
|
509
505
|
|
|
510
506
|
type Bar = {
|
|
511
|
-
[x: number]: number;
|
|
512
|
-
[x: symbol]: unknown;
|
|
513
|
-
bar: Date;
|
|
514
|
-
baz: boolean;
|
|
507
|
+
[x: number]: number;
|
|
508
|
+
[x: symbol]: unknown;
|
|
509
|
+
bar: Date;
|
|
510
|
+
baz: boolean;
|
|
515
511
|
};
|
|
516
512
|
|
|
517
513
|
export type FooBar = Merge<Foo, Bar>;
|
|
@@ -527,14 +523,10 @@ export type FooBar = Merge<Foo, Bar>;
|
|
|
527
523
|
|
|
528
524
|
@category Object
|
|
529
525
|
*/
|
|
530
|
-
type Merge<Destination, Source> =
|
|
531
|
-
Simplify<
|
|
532
|
-
SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>>
|
|
533
|
-
& SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>
|
|
534
|
-
>;
|
|
526
|
+
type Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
|
|
535
527
|
|
|
536
528
|
//#endregion
|
|
537
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
529
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/if-any.d.ts
|
|
538
530
|
/**
|
|
539
531
|
An if-else-like type that resolves depending on whether the given type is `any`.
|
|
540
532
|
|
|
@@ -554,12 +546,10 @@ type ShouldBeBar = IfAny<'not any', 'foo', 'bar'>;
|
|
|
554
546
|
@category Type Guard
|
|
555
547
|
@category Utilities
|
|
556
548
|
*/
|
|
557
|
-
type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
|
|
558
|
-
IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
|
|
559
|
-
);
|
|
549
|
+
type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (IsAny<T> extends true ? TypeIfAny : TypeIfNotAny);
|
|
560
550
|
|
|
561
551
|
//#endregion
|
|
562
|
-
//#region ../../node_modules/.pnpm/type-fest@4.
|
|
552
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/internal/object.d.ts
|
|
563
553
|
/**
|
|
564
554
|
Merges user specified options with default options.
|
|
565
555
|
|
|
@@ -612,26 +602,11 @@ type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOp
|
|
|
612
602
|
// Types of property 'leavesOnly' are incompatible. Type 'string' is not assignable to type 'boolean'.
|
|
613
603
|
```
|
|
614
604
|
*/
|
|
615
|
-
type ApplyDefaultOptions<
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
IfAny<SpecifiedOptions, Defaults,
|
|
621
|
-
IfNever<SpecifiedOptions, Defaults,
|
|
622
|
-
Simplify<Merge<Defaults, {
|
|
623
|
-
[Key in keyof SpecifiedOptions
|
|
624
|
-
as Key extends OptionalKeysOf<Options>
|
|
625
|
-
? Extract<SpecifiedOptions[Key], undefined> extends never
|
|
626
|
-
? Key
|
|
627
|
-
: never
|
|
628
|
-
: Key
|
|
629
|
-
]: SpecifiedOptions[Key]
|
|
630
|
-
}> & Required<Options>> // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
|
|
631
|
-
>>;
|
|
632
|
-
|
|
633
|
-
//#endregion
|
|
634
|
-
//#region ../../node_modules/.pnpm/type-fest@4.40.0/node_modules/type-fest/source/except.d.ts
|
|
605
|
+
type ApplyDefaultOptions<Options extends object, Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>, SpecifiedOptions extends Options> = IfAny<SpecifiedOptions, Defaults, IfNever<SpecifiedOptions, Defaults, Simplify<Merge<Defaults, { [Key in keyof SpecifiedOptions as Key extends OptionalKeysOf<Options> ? Extract<SpecifiedOptions[Key], undefined> extends never ? Key : never : Key]: SpecifiedOptions[Key] }> & Required<Options>> // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
|
|
606
|
+
>>;
|
|
607
|
+
|
|
608
|
+
//#endregion
|
|
609
|
+
//#region ../../node_modules/.pnpm/type-fest@4.41.0/node_modules/type-fest/source/except.d.ts
|
|
635
610
|
/**
|
|
636
611
|
Filter out keys from an object.
|
|
637
612
|
|
|
@@ -661,18 +636,17 @@ type Filtered = Filter<'bar', 'foo'>;
|
|
|
661
636
|
*/
|
|
662
637
|
type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType);
|
|
663
638
|
type ExceptOptions = {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
*/
|
|
671
|
-
requireExactProps?: boolean;
|
|
639
|
+
/**
|
|
640
|
+
Disallow assigning non-specified properties.
|
|
641
|
+
Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`.
|
|
642
|
+
@default false
|
|
643
|
+
*/
|
|
644
|
+
requireExactProps?: boolean;
|
|
672
645
|
};
|
|
673
646
|
type DefaultExceptOptions = {
|
|
674
|
-
|
|
647
|
+
requireExactProps: false;
|
|
675
648
|
};
|
|
649
|
+
|
|
676
650
|
/**
|
|
677
651
|
Create a type from an object type without certain keys.
|
|
678
652
|
|
|
@@ -687,8 +661,8 @@ This type was proposed to the TypeScript team, which declined it, saying they pr
|
|
|
687
661
|
import type {Except} from 'type-fest';
|
|
688
662
|
|
|
689
663
|
type Foo = {
|
|
690
|
-
a: number;
|
|
691
|
-
b: string;
|
|
664
|
+
a: number;
|
|
665
|
+
b: string;
|
|
692
666
|
};
|
|
693
667
|
|
|
694
668
|
type FooWithoutA = Except<Foo, 'a'>;
|
|
@@ -708,10 +682,10 @@ const fooWithoutB: FooWithoutB = {a: 1, b: '2'};
|
|
|
708
682
|
// Consider the following example:
|
|
709
683
|
|
|
710
684
|
type UserData = {
|
|
711
|
-
[metadata: string]: string;
|
|
712
|
-
email: string;
|
|
713
|
-
name: string;
|
|
714
|
-
role: 'admin' | 'user';
|
|
685
|
+
[metadata: string]: string;
|
|
686
|
+
email: string;
|
|
687
|
+
name: string;
|
|
688
|
+
role: 'admin' | 'user';
|
|
715
689
|
};
|
|
716
690
|
|
|
717
691
|
// `Omit` clearly doesn't behave as expected in this case:
|
|
@@ -726,13 +700,8 @@ type PostPayload = Except<UserData, 'email'>;
|
|
|
726
700
|
|
|
727
701
|
@category Object
|
|
728
702
|
*/
|
|
729
|
-
type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {}> =
|
|
730
|
-
|
|
731
|
-
type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = {
|
|
732
|
-
[KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
|
|
733
|
-
} & (Options['requireExactProps'] extends true
|
|
734
|
-
? Partial<Record<KeysType, never>>
|
|
735
|
-
: {});
|
|
703
|
+
type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {}> = _Except<ObjectType, KeysType, ApplyDefaultOptions<ExceptOptions, DefaultExceptOptions, Options>>;
|
|
704
|
+
type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = { [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType] } & (Options['requireExactProps'] extends true ? Partial<Record<KeysType, never>> : {});
|
|
736
705
|
|
|
737
706
|
//#endregion
|
|
738
707
|
//#region src/util/types/ExcludeFunctionProperties.d.ts
|
|
@@ -744,47 +713,27 @@ type KebabToCamel<S extends string> = S extends `${infer T}-${infer U}` ? `${T}$
|
|
|
744
713
|
|
|
745
714
|
//#endregion
|
|
746
715
|
//#region src/util/types/TupleSplitHead.d.ts
|
|
747
|
-
type TupleSplitHead<
|
|
748
|
-
T extends unknown[],
|
|
749
|
-
N extends number
|
|
750
|
-
> = T["length"] extends N ? T : T extends [...infer R, unknown] ? TupleSplitHead<R, N> : never;
|
|
716
|
+
type TupleSplitHead<T extends unknown[], N extends number> = T["length"] extends N ? T : T extends [...infer R, unknown] ? TupleSplitHead<R, N> : never;
|
|
751
717
|
|
|
752
718
|
//#endregion
|
|
753
719
|
//#region src/util/types/TupleSplitTail.d.ts
|
|
754
|
-
type TupleSplitTail<
|
|
755
|
-
T,
|
|
756
|
-
N extends number,
|
|
757
|
-
O extends unknown[] = []
|
|
758
|
-
> = O["length"] extends N ? T : T extends [infer F, ...infer R] ? TupleSplitTail<[...R], N, [...O, F]> : never;
|
|
720
|
+
type TupleSplitTail<T, N extends number, O extends unknown[] = []> = O["length"] extends N ? T : T extends [infer F, ...infer R] ? TupleSplitTail<[...R], N, [...O, F]> : never;
|
|
759
721
|
|
|
760
722
|
//#endregion
|
|
761
723
|
//#region src/util/types/TupleSplit.d.ts
|
|
762
|
-
type TupleSplit<
|
|
763
|
-
T extends unknown[],
|
|
764
|
-
N extends number
|
|
765
|
-
> = [TupleSplitHead<T, N>, TupleSplitTail<T, N>];
|
|
724
|
+
type TupleSplit<T extends unknown[], N extends number> = [TupleSplitHead<T, N>, TupleSplitTail<T, N>];
|
|
766
725
|
|
|
767
726
|
//#endregion
|
|
768
727
|
//#region src/util/types/SkipFirst.d.ts
|
|
769
|
-
type SkipFirst<
|
|
770
|
-
T extends unknown[],
|
|
771
|
-
N extends number
|
|
772
|
-
> = TupleSplit<T, N>[1];
|
|
728
|
+
type SkipFirst<T extends unknown[], N extends number> = TupleSplit<T, N>[1];
|
|
773
729
|
|
|
774
730
|
//#endregion
|
|
775
731
|
//#region src/util/types/TakeFirst.d.ts
|
|
776
|
-
type TakeFirst<
|
|
777
|
-
T extends unknown[],
|
|
778
|
-
N extends number
|
|
779
|
-
> = TupleSplit<T, N>[0];
|
|
732
|
+
type TakeFirst<T extends unknown[], N extends number> = TupleSplit<T, N>[0];
|
|
780
733
|
|
|
781
734
|
//#endregion
|
|
782
735
|
//#region src/util/types/TupleSlice.d.ts
|
|
783
|
-
type TupleSlice<
|
|
784
|
-
T extends unknown[],
|
|
785
|
-
S extends number,
|
|
786
|
-
E extends number = T["length"]
|
|
787
|
-
> = SkipFirst<TakeFirst<T, E>, S>;
|
|
736
|
+
type TupleSlice<T extends unknown[], S extends number, E extends number = T["length"]> = SkipFirst<TakeFirst<T, E>, S>;
|
|
788
737
|
|
|
789
738
|
//#endregion
|
|
790
739
|
//#region src/util/validation/exhaustiveGuard.d.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@esposter/shared",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "A library that contains shared typescript code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/Esposter/Esposter#readme",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist"
|
|
13
13
|
],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
14
17
|
"repository": {
|
|
15
18
|
"type": "git",
|
|
16
19
|
"url": "git+https://github.com/Esposter/Esposter.git"
|
|
@@ -25,5 +28,5 @@
|
|
|
25
28
|
"typecheck": "tsc",
|
|
26
29
|
"export:gen": "ctix build --config ../configuration/.ctirc-ts"
|
|
27
30
|
},
|
|
28
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "fa26fdd42414351b77bd9cf2f9a7b42cc78064c7"
|
|
29
32
|
}
|