serverless-spy 0.0.60 → 0.0.62
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/.jsii +4 -3
- package/README.md +1 -1
- package/_config.yml +14 -3
- package/assets/images/site-logo.png +0 -0
- package/dist/releasetag.txt +1 -1
- package/doc/Lambda.md +2 -0
- package/extension/interceptor.ts +5 -1
- package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js +147 -2
- package/lib/extension/dist/layer/nodejs/node_modules/interceptor.js.map +4 -4
- package/lib/src/ServerlessSpy.js +1 -1
- package/logo/full_logo.png +0 -0
- package/node_modules/serialize-error/error-constructors.d.ts +8 -0
- package/node_modules/serialize-error/error-constructors.js +26 -0
- package/node_modules/serialize-error/index.d.ts +171 -0
- package/node_modules/serialize-error/index.js +205 -0
- package/node_modules/serialize-error/license +9 -0
- package/node_modules/serialize-error/node_modules/type-fest/index.d.ts +95 -0
- package/node_modules/serialize-error/node_modules/type-fest/package.json +52 -0
- package/node_modules/serialize-error/node_modules/type-fest/readme.md +905 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/async-return-type.d.ts +25 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/asyncify.d.ts +33 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/basic.d.ts +45 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/camel-case.d.ts +73 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/camel-cased-properties-deep.d.ts +54 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/camel-cased-properties.d.ts +36 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/conditional-except.d.ts +45 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/conditional-keys.d.ts +47 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/conditional-pick.d.ts +44 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/delimiter-case.d.ts +93 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/delimiter-cased-properties-deep.d.ts +60 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/delimiter-cased-properties.d.ts +37 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/entries.d.ts +62 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/entry.d.ts +65 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/exact.d.ts +73 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/except.d.ts +57 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/fixed-length-array.d.ts +43 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/get.d.ts +184 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/has-optional-keys.d.ts +21 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/has-required-keys.d.ts +59 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/includes.d.ts +22 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/internal.d.ts +59 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/invariant-of.d.ts +76 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/iterable-element.d.ts +54 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/join.d.ts +30 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/jsonify.d.ts +90 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/kebab-case.d.ts +38 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/kebab-cased-properties-deep.d.ts +47 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/kebab-cased-properties.d.ts +30 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/last-array-element.d.ts +28 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/literal-to-primitive.d.ts +36 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/literal-union.d.ts +35 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/merge-exclusive.d.ts +41 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/merge.d.ts +27 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/multidimensional-array.d.ts +43 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/multidimensional-readonly-array.d.ts +47 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/mutable.d.ts +5 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/numeric.d.ts +170 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/observable-like.d.ts +62 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/opaque.d.ts +107 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/optional-keys-of.d.ts +38 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/package-json.d.ts +663 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/partial-deep.d.ts +113 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/partial-on-undefined-deep.d.ts +70 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/pascal-case.d.ts +38 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/pascal-cased-properties-deep.d.ts +54 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/pascal-cased-properties.d.ts +34 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/primitive.d.ts +13 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/promisable.d.ts +25 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/promise-value.d.ts +29 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/readonly-deep.d.ts +85 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/readonly-tuple.d.ts +41 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/remove-index-signature.d.ts +104 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/replace.d.ts +67 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/require-all-or-none.d.ts +36 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/require-at-least-one.d.ts +35 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/require-exactly-one.d.ts +34 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/required-keys-of.d.ts +29 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/schema.d.ts +72 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/screaming-snake-case.d.ts +33 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/set-non-nullable.d.ts +35 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/set-optional.d.ts +35 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/set-required.d.ts +35 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/set-return-type.d.ts +31 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/simplify.d.ts +83 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/snake-case.d.ts +38 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/snake-cased-properties-deep.d.ts +47 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/snake-cased-properties.d.ts +30 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/split.d.ts +29 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/spread.d.ts +85 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/string-key-of.d.ts +25 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/stringified.d.ts +23 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/trim.d.ts +25 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/tsconfig-json.d.ts +1172 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/typed-array.d.ts +17 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/union-to-intersection.d.ts +60 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/value-of.d.ts +42 -0
- package/node_modules/serialize-error/node_modules/type-fest/source/writable.d.ts +40 -0
- package/node_modules/serialize-error/package.json +46 -0
- package/node_modules/serialize-error/readme.md +198 -0
- package/package.json +6 -4
- package/doc/sample_app.md +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
type MapKey<BaseType> = BaseType extends Map<infer KeyType, unknown> ? KeyType : never;
|
|
2
|
+
type MapValue<BaseType> = BaseType extends Map<unknown, infer ValueType> ? ValueType : never;
|
|
3
|
+
|
|
4
|
+
export type ArrayEntry<BaseType extends readonly unknown[]> = [number, BaseType[number]];
|
|
5
|
+
export type MapEntry<BaseType> = [MapKey<BaseType>, MapValue<BaseType>];
|
|
6
|
+
export type ObjectEntry<BaseType> = [keyof BaseType, BaseType[keyof BaseType]];
|
|
7
|
+
export type SetEntry<BaseType> = BaseType extends Set<infer ItemType> ? [ItemType, ItemType] : never;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entry` type will return the type of that collection's entry.
|
|
11
|
+
|
|
12
|
+
For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable.
|
|
13
|
+
|
|
14
|
+
@see `Entries` if you want to just access the type of the array of entries (which is the return of the `.entries()` method).
|
|
15
|
+
|
|
16
|
+
@example
|
|
17
|
+
```
|
|
18
|
+
import type {Entry} from 'type-fest';
|
|
19
|
+
|
|
20
|
+
interface Example {
|
|
21
|
+
someKey: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const manipulatesEntry = (example: Entry<Example>) => [
|
|
25
|
+
// Does some arbitrary processing on the key (with type information available)
|
|
26
|
+
example[0].toUpperCase(),
|
|
27
|
+
|
|
28
|
+
// Does some arbitrary processing on the value (with type information available)
|
|
29
|
+
example[1].toFixed(),
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const example: Example = {someKey: 1};
|
|
33
|
+
const entry = Object.entries(example)[0] as Entry<Example>;
|
|
34
|
+
const output = manipulatesEntry(entry);
|
|
35
|
+
|
|
36
|
+
// Objects
|
|
37
|
+
const objectExample = {a: 1};
|
|
38
|
+
const objectEntry: Entry<typeof objectExample> = ['a', 1];
|
|
39
|
+
|
|
40
|
+
// Arrays
|
|
41
|
+
const arrayExample = ['a', 1];
|
|
42
|
+
const arrayEntryString: Entry<typeof arrayExample> = [0, 'a'];
|
|
43
|
+
const arrayEntryNumber: Entry<typeof arrayExample> = [1, 1];
|
|
44
|
+
|
|
45
|
+
// Maps
|
|
46
|
+
const mapExample = new Map([['a', 1]]);
|
|
47
|
+
const mapEntry: Entry<typeof mapExample> = ['a', 1];
|
|
48
|
+
|
|
49
|
+
// Sets
|
|
50
|
+
const setExample = new Set(['a', 1]);
|
|
51
|
+
const setEntryString: Entry<typeof setExample> = ['a', 'a'];
|
|
52
|
+
const setEntryNumber: Entry<typeof setExample> = [1, 1];
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
@category Object
|
|
56
|
+
@category Map
|
|
57
|
+
@category Array
|
|
58
|
+
@category Set
|
|
59
|
+
*/
|
|
60
|
+
export type Entry<BaseType> =
|
|
61
|
+
BaseType extends Map<unknown, unknown> ? MapEntry<BaseType>
|
|
62
|
+
: BaseType extends Set<unknown> ? SetEntry<BaseType>
|
|
63
|
+
: BaseType extends readonly unknown[] ? ArrayEntry<BaseType>
|
|
64
|
+
: BaseType extends object ? ObjectEntry<BaseType>
|
|
65
|
+
: never;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type {KeysOfUnion} from './internal';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Extract the element of an array that also works for array union.
|
|
5
|
+
|
|
6
|
+
Returns `never` if T is not an array.
|
|
7
|
+
|
|
8
|
+
It creates a type-safe way to access the element type of `unknown` type.
|
|
9
|
+
*/
|
|
10
|
+
type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
|
|
14
|
+
|
|
15
|
+
It creates a type-safe way to access the member type of `unknown` type.
|
|
16
|
+
*/
|
|
17
|
+
type ObjectValue<T, K> = K extends keyof T ? T[K] : never;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`.
|
|
21
|
+
- Generate a list of keys that exists in `InputType` but not in `ParameterType`.
|
|
22
|
+
- Mark these excess keys as `never`.
|
|
23
|
+
*/
|
|
24
|
+
type ExactObject<ParameterType, InputType> = {[Key in keyof ParameterType]: Exact<ParameterType[Key], ObjectValue<InputType, Key>>}
|
|
25
|
+
& Record<Exclude<keyof InputType, KeysOfUnion<ParameterType>>, never>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared.
|
|
29
|
+
|
|
30
|
+
This is useful for function type-guarding to reject arguments with excess properties. Due to the nature of TypeScript, it does not complain if excess properties are provided unless the provided value is an object literal.
|
|
31
|
+
|
|
32
|
+
*Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/12936) if you want to have this type as a built-in in TypeScript.*
|
|
33
|
+
|
|
34
|
+
@example
|
|
35
|
+
```
|
|
36
|
+
type OnlyAcceptName = {name: string};
|
|
37
|
+
|
|
38
|
+
function onlyAcceptName(args: OnlyAcceptName) {}
|
|
39
|
+
|
|
40
|
+
// TypeScript complains about excess properties when an object literal is provided.
|
|
41
|
+
onlyAcceptName({name: 'name', id: 1});
|
|
42
|
+
//=> `id` is excess
|
|
43
|
+
|
|
44
|
+
// TypeScript does not complain about excess properties when the provided value is a variable (not an object literal).
|
|
45
|
+
const invalidInput = {name: 'name', id: 1};
|
|
46
|
+
onlyAcceptName(invalidInput); // No errors
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Having `Exact` allows TypeScript to reject excess properties.
|
|
50
|
+
|
|
51
|
+
@example
|
|
52
|
+
```
|
|
53
|
+
import {Exact} from 'type-fest';
|
|
54
|
+
|
|
55
|
+
type OnlyAcceptName = {name: string};
|
|
56
|
+
|
|
57
|
+
function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(args: T) {}
|
|
58
|
+
|
|
59
|
+
const invalidInput = {name: 'name', id: 1};
|
|
60
|
+
onlyAcceptNameImproved(invalidInput); // Compilation error
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
[Read more](https://stackoverflow.com/questions/49580725/is-it-possible-to-restrict-typescript-object-to-contain-only-properties-defined)
|
|
64
|
+
|
|
65
|
+
@category Utilities
|
|
66
|
+
*/
|
|
67
|
+
export type Exact<ParameterType, InputType> =
|
|
68
|
+
// Convert union of array to array of union: A[] & B[] => (A & B)[]
|
|
69
|
+
ParameterType extends unknown[] ? Array<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
70
|
+
// In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray.
|
|
71
|
+
: ParameterType extends readonly unknown[] ? ReadonlyArray<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
72
|
+
: ParameterType extends object ? ExactObject<ParameterType, InputType>
|
|
73
|
+
: ParameterType;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type {IsEqual} from './internal';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Filter out keys from an object.
|
|
5
|
+
|
|
6
|
+
Returns `never` if `Exclude` is strictly equal to `Key`.
|
|
7
|
+
Returns `never` if `Key` extends `Exclude`.
|
|
8
|
+
Returns `Key` otherwise.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
```
|
|
12
|
+
type Filtered = Filter<'foo', 'foo'>;
|
|
13
|
+
//=> never
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
@example
|
|
17
|
+
```
|
|
18
|
+
type Filtered = Filter<'bar', string>;
|
|
19
|
+
//=> never
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
@example
|
|
23
|
+
```
|
|
24
|
+
type Filtered = Filter<'bar', 'foo'>;
|
|
25
|
+
//=> 'bar'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
@see {Except}
|
|
29
|
+
*/
|
|
30
|
+
type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
Create a type from an object type without certain keys.
|
|
34
|
+
|
|
35
|
+
This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically.
|
|
36
|
+
|
|
37
|
+
This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)).
|
|
38
|
+
|
|
39
|
+
@example
|
|
40
|
+
```
|
|
41
|
+
import type {Except} from 'type-fest';
|
|
42
|
+
|
|
43
|
+
type Foo = {
|
|
44
|
+
a: number;
|
|
45
|
+
b: string;
|
|
46
|
+
c: boolean;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
type FooWithoutA = Except<Foo, 'a' | 'c'>;
|
|
50
|
+
//=> {b: string};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
@category Object
|
|
54
|
+
*/
|
|
55
|
+
export type Except<ObjectType, KeysType extends keyof ObjectType> = {
|
|
56
|
+
[KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
|
|
57
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Methods to exclude.
|
|
3
|
+
*/
|
|
4
|
+
type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Create a type that represents an array of the given type and length. The array's length and the `Array` prototype methods that manipulate its length are excluded in the resulting type.
|
|
8
|
+
|
|
9
|
+
Please participate in [this issue](https://github.com/microsoft/TypeScript/issues/26223) if you want to have a similiar type built into TypeScript.
|
|
10
|
+
|
|
11
|
+
Use-cases:
|
|
12
|
+
- Declaring fixed-length tuples or arrays with a large number of items.
|
|
13
|
+
- Creating a range union (for example, `0 | 1 | 2 | 3 | 4` from the keys of such a type) without having to resort to recursive types.
|
|
14
|
+
- Creating an array of coordinates with a static length, for example, length of 3 for a 3D vector.
|
|
15
|
+
|
|
16
|
+
Note: This type does not prevent out-of-bounds access. Prefer `ReadonlyTuple` unless you need mutability.
|
|
17
|
+
|
|
18
|
+
@example
|
|
19
|
+
```
|
|
20
|
+
import type {FixedLengthArray} from 'type-fest';
|
|
21
|
+
|
|
22
|
+
type FencingTeam = FixedLengthArray<string, 3>;
|
|
23
|
+
|
|
24
|
+
const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert'];
|
|
25
|
+
|
|
26
|
+
const homeFencingTeam: FencingTeam = ['George', 'John'];
|
|
27
|
+
//=> error TS2322: Type string[] is not assignable to type 'FencingTeam'
|
|
28
|
+
|
|
29
|
+
guestFencingTeam.push('Sam');
|
|
30
|
+
//=> error TS2339: Property 'push' does not exist on type 'FencingTeam'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
@category Array
|
|
34
|
+
@see ReadonlyTuple
|
|
35
|
+
*/
|
|
36
|
+
export type FixedLengthArray<Element, Length extends number, ArrayPrototype = [Element, ...Element[]]> = Pick<
|
|
37
|
+
ArrayPrototype,
|
|
38
|
+
Exclude<keyof ArrayPrototype, ArrayLengthMutationKeys>
|
|
39
|
+
> & {
|
|
40
|
+
[index: number]: Element;
|
|
41
|
+
[Symbol.iterator]: () => IterableIterator<Element>;
|
|
42
|
+
readonly length: Length;
|
|
43
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type {StringDigit} from '../source/internal';
|
|
2
|
+
import type {Split} from './split';
|
|
3
|
+
import type {StringKeyOf} from './string-key-of';
|
|
4
|
+
|
|
5
|
+
type GetOptions = {
|
|
6
|
+
strict?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
Like the `Get` type but receives an array of strings as a path parameter.
|
|
11
|
+
*/
|
|
12
|
+
type GetWithPath<BaseType, Keys extends readonly string[], Options extends GetOptions = {}> =
|
|
13
|
+
Keys extends []
|
|
14
|
+
? BaseType
|
|
15
|
+
: Keys extends readonly [infer Head, ...infer Tail]
|
|
16
|
+
? GetWithPath<
|
|
17
|
+
PropertyOf<BaseType, Extract<Head, string>, Options>,
|
|
18
|
+
Extract<Tail, string[]>,
|
|
19
|
+
Options
|
|
20
|
+
>
|
|
21
|
+
: never;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
Adds `undefined` to `Type` if `strict` is enabled.
|
|
25
|
+
*/
|
|
26
|
+
type Strictify<Type, Options extends GetOptions> =
|
|
27
|
+
Options['strict'] extends true ? Type | undefined : Type;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
If `Options['strict']` is `true`, includes `undefined` in the returned type when accessing properties on `Record<string, any>`.
|
|
31
|
+
|
|
32
|
+
Known limitations:
|
|
33
|
+
- Does not include `undefined` in the type on object types with an index signature (for example, `{a: string; [key: string]: string}`).
|
|
34
|
+
*/
|
|
35
|
+
type StrictPropertyOf<BaseType, Key extends keyof BaseType, Options extends GetOptions> =
|
|
36
|
+
Record<string, any> extends BaseType
|
|
37
|
+
? string extends keyof BaseType
|
|
38
|
+
? Strictify<BaseType[Key], Options> // Record<string, any>
|
|
39
|
+
: BaseType[Key] // Record<'a' | 'b', any> (Records with a string union as keys have required properties)
|
|
40
|
+
: BaseType[Key];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
Splits a dot-prop style path into a tuple comprised of the properties in the path. Handles square-bracket notation.
|
|
44
|
+
|
|
45
|
+
@example
|
|
46
|
+
```
|
|
47
|
+
ToPath<'foo.bar.baz'>
|
|
48
|
+
//=> ['foo', 'bar', 'baz']
|
|
49
|
+
|
|
50
|
+
ToPath<'foo[0].bar.baz'>
|
|
51
|
+
//=> ['foo', '0', 'bar', 'baz']
|
|
52
|
+
```
|
|
53
|
+
*/
|
|
54
|
+
type ToPath<S extends string> = Split<FixPathSquareBrackets<S>, '.'>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
Replaces square-bracketed dot notation with dots, for example, `foo[0].bar` -> `foo.0.bar`.
|
|
58
|
+
*/
|
|
59
|
+
type FixPathSquareBrackets<Path extends string> =
|
|
60
|
+
Path extends `[${infer Head}]${infer Tail}`
|
|
61
|
+
? Tail extends `[${string}`
|
|
62
|
+
? `${Head}.${FixPathSquareBrackets<Tail>}`
|
|
63
|
+
: `${Head}${FixPathSquareBrackets<Tail>}`
|
|
64
|
+
: Path extends `${infer Head}[${infer Middle}]${infer Tail}`
|
|
65
|
+
? `${Head}.${FixPathSquareBrackets<`[${Middle}]${Tail}`>}`
|
|
66
|
+
: Path;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
Returns true if `LongString` is made up out of `Substring` repeated 0 or more times.
|
|
70
|
+
|
|
71
|
+
@example
|
|
72
|
+
```
|
|
73
|
+
ConsistsOnlyOf<'aaa', 'a'> //=> true
|
|
74
|
+
ConsistsOnlyOf<'ababab', 'ab'> //=> true
|
|
75
|
+
ConsistsOnlyOf<'aBa', 'a'> //=> false
|
|
76
|
+
ConsistsOnlyOf<'', 'a'> //=> true
|
|
77
|
+
```
|
|
78
|
+
*/
|
|
79
|
+
type ConsistsOnlyOf<LongString extends string, Substring extends string> =
|
|
80
|
+
LongString extends ''
|
|
81
|
+
? true
|
|
82
|
+
: LongString extends `${Substring}${infer Tail}`
|
|
83
|
+
? ConsistsOnlyOf<Tail, Substring>
|
|
84
|
+
: false;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
Convert a type which may have number keys to one with string keys, making it possible to index using strings retrieved from template types.
|
|
88
|
+
|
|
89
|
+
@example
|
|
90
|
+
```
|
|
91
|
+
type WithNumbers = {foo: string; 0: boolean};
|
|
92
|
+
type WithStrings = WithStringKeys<WithNumbers>;
|
|
93
|
+
|
|
94
|
+
type WithNumbersKeys = keyof WithNumbers;
|
|
95
|
+
//=> 'foo' | 0
|
|
96
|
+
type WithStringsKeys = keyof WithStrings;
|
|
97
|
+
//=> 'foo' | '0'
|
|
98
|
+
```
|
|
99
|
+
*/
|
|
100
|
+
type WithStringKeys<BaseType> = {
|
|
101
|
+
[Key in StringKeyOf<BaseType>]: UncheckedIndex<BaseType, Key>
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
Perform a `T[U]` operation if `T` supports indexing.
|
|
106
|
+
*/
|
|
107
|
+
type UncheckedIndex<T, U extends string | number> = [T] extends [Record<string | number, any>] ? T[U] : never;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
Get a property of an object or array. Works when indexing arrays using number-literal-strings, for example, `PropertyOf<number[], '0'> = number`, and when indexing objects with number keys.
|
|
111
|
+
|
|
112
|
+
Note:
|
|
113
|
+
- Returns `unknown` if `Key` is not a property of `BaseType`, since TypeScript uses structural typing, and it cannot be guaranteed that extra properties unknown to the type system will exist at runtime.
|
|
114
|
+
- Returns `undefined` from nullish values, to match the behaviour of most deep-key libraries like `lodash`, `dot-prop`, etc.
|
|
115
|
+
*/
|
|
116
|
+
type PropertyOf<BaseType, Key extends string, Options extends GetOptions = {}> =
|
|
117
|
+
BaseType extends null | undefined
|
|
118
|
+
? undefined
|
|
119
|
+
: Key extends keyof BaseType
|
|
120
|
+
? StrictPropertyOf<BaseType, Key, Options>
|
|
121
|
+
: BaseType extends [] | [unknown, ...unknown[]]
|
|
122
|
+
? unknown // It's a tuple, but `Key` did not extend `keyof BaseType`. So the index is out of bounds.
|
|
123
|
+
: BaseType extends {
|
|
124
|
+
[n: number]: infer Item;
|
|
125
|
+
length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`.
|
|
126
|
+
}
|
|
127
|
+
? (
|
|
128
|
+
ConsistsOnlyOf<Key, StringDigit> extends true
|
|
129
|
+
? Strictify<Item, Options>
|
|
130
|
+
: unknown
|
|
131
|
+
)
|
|
132
|
+
: Key extends keyof WithStringKeys<BaseType>
|
|
133
|
+
? StrictPropertyOf<WithStringKeys<BaseType>, Key, Options>
|
|
134
|
+
: unknown;
|
|
135
|
+
|
|
136
|
+
// This works by first splitting the path based on `.` and `[...]` characters into a tuple of string keys. Then it recursively uses the head key to get the next property of the current object, until there are no keys left. Number keys extract the item type from arrays, or are converted to strings to extract types from tuples and dictionaries with number keys.
|
|
137
|
+
/**
|
|
138
|
+
Get a deeply-nested property from an object using a key path, like Lodash's `.get()` function.
|
|
139
|
+
|
|
140
|
+
Use-case: Retrieve a property from deep inside an API response or some other complex object.
|
|
141
|
+
|
|
142
|
+
@example
|
|
143
|
+
```
|
|
144
|
+
import type {Get} from 'type-fest';
|
|
145
|
+
import * as lodash from 'lodash';
|
|
146
|
+
|
|
147
|
+
const get = <BaseType, Path extends string | readonly string[]>(object: BaseType, path: Path): Get<BaseType, Path> =>
|
|
148
|
+
lodash.get(object, path);
|
|
149
|
+
|
|
150
|
+
interface ApiResponse {
|
|
151
|
+
hits: {
|
|
152
|
+
hits: Array<{
|
|
153
|
+
_id: string
|
|
154
|
+
_source: {
|
|
155
|
+
name: Array<{
|
|
156
|
+
given: string[]
|
|
157
|
+
family: string
|
|
158
|
+
}>
|
|
159
|
+
birthDate: string
|
|
160
|
+
}
|
|
161
|
+
}>
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const getName = (apiResponse: ApiResponse) =>
|
|
166
|
+
get(apiResponse, 'hits.hits[0]._source.name');
|
|
167
|
+
//=> Array<{given: string[]; family: string}>
|
|
168
|
+
|
|
169
|
+
// Path also supports a readonly array of strings
|
|
170
|
+
const getNameWithPathArray = (apiResponse: ApiResponse) =>
|
|
171
|
+
get(apiResponse, ['hits','hits', '0', '_source', 'name'] as const);
|
|
172
|
+
//=> Array<{given: string[]; family: string}>
|
|
173
|
+
|
|
174
|
+
// Strict mode:
|
|
175
|
+
Get<string[], '3', {strict: true}> //=> string | undefined
|
|
176
|
+
Get<Record<string, string>, 'foo', {strict: true}> // => string | undefined
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
@category Object
|
|
180
|
+
@category Array
|
|
181
|
+
@category Template literal
|
|
182
|
+
*/
|
|
183
|
+
export type Get<BaseType, Path extends string | readonly string[], Options extends GetOptions = {}> =
|
|
184
|
+
GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {OptionalKeysOf} from './optional-keys-of';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Creates a type that represents `true` or `false` depending on whether the given type has any optional fields.
|
|
5
|
+
|
|
6
|
+
This is useful when you want to create an API whose behavior depends on the presence or absence of optional fields.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {HasOptionalKeys, OptionalKeysOf} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
type UpdateService<Entity extends object> = {
|
|
13
|
+
removeField: HasOptionalKeys<Entity> extends true
|
|
14
|
+
? (field: OptionalKeysOf<Entity>) => Promise<void>
|
|
15
|
+
: never
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
@category Utilities
|
|
20
|
+
*/
|
|
21
|
+
export type HasOptionalKeys<BaseType extends object> = OptionalKeysOf<BaseType> extends never ? false : true;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {RequiredKeysOf} from './required-keys-of';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Creates a type that represents `true` or `false` depending on whether the given type has any required fields.
|
|
5
|
+
|
|
6
|
+
This is useful when you want to create an API whose behavior depends on the presence or absence of required fields.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {HasRequiredKeys} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
type GeneratorOptions<Template extends object> = {
|
|
13
|
+
prop1: number;
|
|
14
|
+
prop2: string;
|
|
15
|
+
} & (HasRequiredKeys<Template> extends true
|
|
16
|
+
? {template: Template}
|
|
17
|
+
: {template?: Template});
|
|
18
|
+
|
|
19
|
+
interface Template1 {
|
|
20
|
+
optionalSubParam?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface Template2 {
|
|
24
|
+
requiredSubParam: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type Options1 = GeneratorOptions<Template1>;
|
|
28
|
+
type Options2 = GeneratorOptions<Template2>;
|
|
29
|
+
|
|
30
|
+
const optA: Options1 = {
|
|
31
|
+
prop1: 0,
|
|
32
|
+
prop2: 'hi'
|
|
33
|
+
};
|
|
34
|
+
const optB: Options1 = {
|
|
35
|
+
prop1: 0,
|
|
36
|
+
prop2: 'hi',
|
|
37
|
+
template: {}
|
|
38
|
+
};
|
|
39
|
+
const optC: Options1 = {
|
|
40
|
+
prop1: 0,
|
|
41
|
+
prop2: 'hi',
|
|
42
|
+
template: {
|
|
43
|
+
optionalSubParam: 'optional value'
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const optD: Options2 = {
|
|
48
|
+
prop1: 0,
|
|
49
|
+
prop2: 'hi',
|
|
50
|
+
template: {
|
|
51
|
+
requiredSubParam: 'required value'
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
@category Utilities
|
|
58
|
+
*/
|
|
59
|
+
export type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type {IsEqual} from './internal';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Returns a boolean for whether the given array includes the given item.
|
|
5
|
+
|
|
6
|
+
This can be useful if another type wants to make a decision based on whether the array includes that item.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {Includes} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
type hasRed<array extends any[]> = Includes<array, 'red'>;
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
@category Array
|
|
16
|
+
*/
|
|
17
|
+
export type Includes<Value extends readonly any[], Item> =
|
|
18
|
+
Value extends readonly [Value[0], ...infer rest]
|
|
19
|
+
? IsEqual<Value[0], Item> extends true
|
|
20
|
+
? true
|
|
21
|
+
: Includes<rest, Item>
|
|
22
|
+
: false;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type {Primitive} from './primitive';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Returns a boolean for whether the two given types are equal.
|
|
5
|
+
|
|
6
|
+
@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
|
|
7
|
+
@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796
|
|
8
|
+
*/
|
|
9
|
+
export type IsEqual<T, U> =
|
|
10
|
+
(<G>() => G extends T ? 1 : 2) extends
|
|
11
|
+
(<G>() => G extends U ? 1 : 2)
|
|
12
|
+
? true
|
|
13
|
+
: false;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
Infer the length of the given array `<T>`.
|
|
17
|
+
|
|
18
|
+
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
19
|
+
*/
|
|
20
|
+
type TupleLength<T extends readonly unknown[]> = T extends {readonly length: infer L} ? L : never;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Create a tuple type of the given length `<L>`.
|
|
24
|
+
|
|
25
|
+
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
26
|
+
*/
|
|
27
|
+
type BuildTuple<L extends number, T extends readonly unknown[] = []> = T extends {readonly length: L}
|
|
28
|
+
? T
|
|
29
|
+
: BuildTuple<L, [...T, unknown]>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
Create a tuple of length `A` and a tuple composed of two other tuples,
|
|
33
|
+
the inferred tuple `U` and a tuple of length `B`, then extracts the length of tuple `U`.
|
|
34
|
+
|
|
35
|
+
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
36
|
+
*/
|
|
37
|
+
export type Subtract<A extends number, B extends number> = BuildTuple<A> extends [...(infer U), ...BuildTuple<B>]
|
|
38
|
+
? TupleLength<U>
|
|
39
|
+
: never;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
Matches any primitive, `Date`, or `RegExp` value.
|
|
43
|
+
*/
|
|
44
|
+
export type BuiltIns = Primitive | Date | RegExp;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
Gets keys from a type. Similar to `keyof` but this one also works for union types.
|
|
48
|
+
|
|
49
|
+
The reason a simple `keyof Union` does not work is because `keyof` always returns the accessible keys of a type. In the case of a union, that will only be the common keys.
|
|
50
|
+
|
|
51
|
+
@link https://stackoverflow.com/a/49402091
|
|
52
|
+
*/
|
|
53
|
+
export type KeysOfUnion<T> = T extends T ? keyof T : never;
|
|
54
|
+
|
|
55
|
+
export type UpperCaseCharacters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
56
|
+
|
|
57
|
+
export type WordSeparators = '-' | '_' | ' ';
|
|
58
|
+
|
|
59
|
+
export type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type {Opaque} from './opaque';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Create an [invariant type](https://basarat.gitbook.io/typescript/type-system/type-compatibility#footnote-invariance), which is a type that does not accept supertypes and subtypes.
|
|
5
|
+
|
|
6
|
+
Use-case:
|
|
7
|
+
- Prevent runtime errors that may occur due to assigning subtypes to supertypes.
|
|
8
|
+
- Improve type signature of object methods like [`Object.keys()` or `Object.entries()`](https://github.com/microsoft/TypeScript/pull/12253#issuecomment-263132208) by sealing the object type.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
```
|
|
12
|
+
import type {InvariantOf} from 'type-fest';
|
|
13
|
+
|
|
14
|
+
class Animal {
|
|
15
|
+
constructor(public name: string){}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class Cat extends Animal {
|
|
19
|
+
meow() {}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let animalArray: Animal[] = [animal];
|
|
23
|
+
let catArray: Cat[] = [cat];
|
|
24
|
+
|
|
25
|
+
animalArray = catArray; // Okay if covariant
|
|
26
|
+
animalArray.push(new Animal('another animal')); // Pushed an animal into catArray
|
|
27
|
+
catArray.forEach(c => c.meow()); // Allowed but, error at runtime
|
|
28
|
+
|
|
29
|
+
let invariantAnimalArray: InvariantOf<Animal>[] = [animal] as InvariantOf<Animal>[];
|
|
30
|
+
let invariantCatArray: InvariantOf<Cat>[] = [cat] as InvariantOf<Cat>[];
|
|
31
|
+
|
|
32
|
+
invariantAnimalArray = invariantCatArray; // Error: Type 'InvariantOf<Cat>[]' is not assignable to type 'InvariantOf<Animal>[]'.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
@example
|
|
36
|
+
```
|
|
37
|
+
import type {InvariantOf} from 'type-fest';
|
|
38
|
+
|
|
39
|
+
// In covariance (default)
|
|
40
|
+
|
|
41
|
+
interface FooBar {
|
|
42
|
+
foo: number;
|
|
43
|
+
bar: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface FooBarBaz extends FooBar {
|
|
47
|
+
baz: boolean
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
declare const fooBar: FooBar
|
|
51
|
+
declare const fooBarBaz: FooBarBaz
|
|
52
|
+
|
|
53
|
+
function keyOfFooBar(fooBar: FooBar) {
|
|
54
|
+
return Object.keys(fooBar) as (keyof FooBar)[]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
keyOfFooBar(fooBar) //=> (keyof FooBar)[]
|
|
58
|
+
keyOfFooBar(fooBarBaz) //=> (keyof FooBar)[] but, (keyof FooBarBaz)[] at runtime
|
|
59
|
+
|
|
60
|
+
// In invariance
|
|
61
|
+
|
|
62
|
+
export function invariantOf<Type>(value: Type): InvariantOf<Type> {
|
|
63
|
+
return value as InvariantOf<Type>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function keyOfInvariantFooBar(fooBar: InvariantOf<FooBar>) {
|
|
67
|
+
return Object.keys(fooBar) as (keyof FooBar)[]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
keyOfInvariantFooBar(invariantOf(fooBar)); // (keyof FooBar)[]
|
|
71
|
+
keyOfInvariantFooBar(invariantOf(fooBarBaz)); // Error: Argument of type 'InvariantOf<FooBarBaz>' is not assignable to parameter of type 'InvariantOf<FooBar>'.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
@category Type
|
|
75
|
+
*/
|
|
76
|
+
export type InvariantOf<Type> = Opaque<Type, (argument: Type) => Type>;
|