@depup/type-fest 5.4.4-depup.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/README.md +25 -0
- package/index.d.ts +211 -0
- package/license-cc0 +121 -0
- package/license-mit +9 -0
- package/package.json +85 -0
- package/readme.md +1052 -0
- package/source/all-extend.d.ts +120 -0
- package/source/all-union-fields.d.ts +91 -0
- package/source/and.d.ts +81 -0
- package/source/array-element.d.ts +46 -0
- package/source/array-indices.d.ts +25 -0
- package/source/array-reverse.d.ts +84 -0
- package/source/array-slice.d.ts +132 -0
- package/source/array-splice.d.ts +104 -0
- package/source/array-tail.d.ts +70 -0
- package/source/array-values.d.ts +24 -0
- package/source/arrayable.d.ts +31 -0
- package/source/async-return-type.d.ts +28 -0
- package/source/asyncify.d.ts +25 -0
- package/source/basic.d.ts +38 -0
- package/source/camel-case.d.ts +92 -0
- package/source/camel-cased-properties-deep.d.ts +99 -0
- package/source/camel-cased-properties.d.ts +45 -0
- package/source/characters.d.ts +67 -0
- package/source/conditional-except.d.ts +47 -0
- package/source/conditional-keys.d.ts +63 -0
- package/source/conditional-pick-deep.d.ts +120 -0
- package/source/conditional-pick.d.ts +46 -0
- package/source/conditional-simplify-deep.d.ts +73 -0
- package/source/conditional-simplify.d.ts +50 -0
- package/source/delimiter-case.d.ts +77 -0
- package/source/delimiter-cased-properties-deep.d.ts +108 -0
- package/source/delimiter-cased-properties.d.ts +48 -0
- package/source/distributed-omit.d.ts +96 -0
- package/source/distributed-pick.d.ts +92 -0
- package/source/empty-object.d.ts +51 -0
- package/source/entries.d.ts +64 -0
- package/source/entry.d.ts +67 -0
- package/source/exact.d.ts +73 -0
- package/source/except.d.ts +112 -0
- package/source/exclude-rest-element.d.ts +40 -0
- package/source/exclude-strict.d.ts +51 -0
- package/source/exclusify-union.d.ts +147 -0
- package/source/extends-strict.d.ts +44 -0
- package/source/extract-rest-element.d.ts +30 -0
- package/source/extract-strict.d.ts +51 -0
- package/source/find-global-type.d.ts +68 -0
- package/source/fixed-length-array.d.ts +97 -0
- package/source/get.d.ts +227 -0
- package/source/global-this.d.ts +24 -0
- package/source/globals/index.d.ts +3 -0
- package/source/globals/observable-like.d.ts +78 -0
- package/source/greater-than-or-equal.d.ts +30 -0
- package/source/greater-than.d.ts +58 -0
- package/source/has-optional-keys.d.ts +23 -0
- package/source/has-readonly-keys.d.ts +23 -0
- package/source/has-required-keys.d.ts +61 -0
- package/source/has-writable-keys.d.ts +23 -0
- package/source/if-any.d.ts +28 -0
- package/source/if-empty-object.d.ts +30 -0
- package/source/if-never.d.ts +28 -0
- package/source/if-null.d.ts +28 -0
- package/source/if-unknown.d.ts +28 -0
- package/source/if.d.ts +102 -0
- package/source/includes.d.ts +24 -0
- package/source/int-closed-range.d.ts +47 -0
- package/source/int-range.d.ts +69 -0
- package/source/internal/array.d.ts +151 -0
- package/source/internal/characters.d.ts +65 -0
- package/source/internal/enforce-optional.d.ts +49 -0
- package/source/internal/index.d.ts +11 -0
- package/source/internal/keys.d.ts +100 -0
- package/source/internal/numeric.d.ts +151 -0
- package/source/internal/object.d.ts +292 -0
- package/source/internal/string.d.ts +202 -0
- package/source/internal/tuple.d.ts +79 -0
- package/source/internal/type.d.ts +164 -0
- package/source/invariant-of.d.ts +85 -0
- package/source/is-any.d.ts +31 -0
- package/source/is-equal.d.ts +42 -0
- package/source/is-float.d.ts +43 -0
- package/source/is-integer.d.ts +60 -0
- package/source/is-literal.d.ts +315 -0
- package/source/is-lowercase.d.ts +38 -0
- package/source/is-never.d.ts +56 -0
- package/source/is-null.d.ts +22 -0
- package/source/is-nullable.d.ts +30 -0
- package/source/is-optional-key-of.d.ts +51 -0
- package/source/is-optional.d.ts +28 -0
- package/source/is-readonly-key-of.d.ts +55 -0
- package/source/is-required-key-of.d.ts +51 -0
- package/source/is-tuple.d.ts +92 -0
- package/source/is-undefined.d.ts +22 -0
- package/source/is-union.d.ts +40 -0
- package/source/is-unknown.d.ts +43 -0
- package/source/is-uppercase.d.ts +38 -0
- package/source/is-writable-key-of.d.ts +51 -0
- package/source/iterable-element.d.ts +66 -0
- package/source/join.d.ts +79 -0
- package/source/json-value.d.ts +33 -0
- package/source/jsonifiable.d.ts +37 -0
- package/source/jsonify.d.ts +127 -0
- package/source/kebab-case.d.ts +46 -0
- package/source/kebab-cased-properties-deep.d.ts +65 -0
- package/source/kebab-cased-properties.d.ts +42 -0
- package/source/key-as-string.d.ts +27 -0
- package/source/keys-of-union.d.ts +44 -0
- package/source/last-array-element.d.ts +36 -0
- package/source/less-than-or-equal.d.ts +24 -0
- package/source/less-than.d.ts +28 -0
- package/source/literal-to-primitive-deep.d.ts +71 -0
- package/source/literal-to-primitive.d.ts +38 -0
- package/source/literal-union.d.ts +39 -0
- package/source/merge-deep.d.ts +495 -0
- package/source/merge-exclusive.d.ts +45 -0
- package/source/merge.d.ts +62 -0
- package/source/multidimensional-array.d.ts +38 -0
- package/source/multidimensional-readonly-array.d.ts +38 -0
- package/source/non-empty-object.d.ts +38 -0
- package/source/non-empty-string.d.ts +32 -0
- package/source/non-empty-tuple.d.ts +24 -0
- package/source/numeric.d.ts +226 -0
- package/source/object-merge.d.ts +194 -0
- package/source/omit-deep.d.ts +154 -0
- package/source/omit-index-signature.d.ts +98 -0
- package/source/opaque.d.ts +3 -0
- package/source/optional-keys-of.d.ts +46 -0
- package/source/or.d.ts +89 -0
- package/source/override-properties.d.ts +43 -0
- package/source/package-json.d.ts +710 -0
- package/source/partial-deep.d.ts +155 -0
- package/source/partial-on-undefined-deep.d.ts +81 -0
- package/source/pascal-case.d.ts +51 -0
- package/source/pascal-cased-properties-deep.d.ts +72 -0
- package/source/pascal-cased-properties.d.ts +42 -0
- package/source/paths.d.ts +241 -0
- package/source/pick-deep.d.ts +152 -0
- package/source/pick-index-signature.d.ts +52 -0
- package/source/primitive.d.ts +15 -0
- package/source/promisable.d.ts +27 -0
- package/source/readonly-deep.d.ts +116 -0
- package/source/readonly-keys-of.d.ts +38 -0
- package/source/readonly-tuple.d.ts +34 -0
- package/source/remove-prefix.d.ts +132 -0
- package/source/replace.d.ts +87 -0
- package/source/require-all-or-none.d.ts +54 -0
- package/source/require-at-least-one.d.ts +50 -0
- package/source/require-exactly-one.d.ts +48 -0
- package/source/require-one-or-none.d.ts +49 -0
- package/source/required-deep.d.ts +76 -0
- package/source/required-keys-of.d.ts +38 -0
- package/source/schema.d.ts +119 -0
- package/source/screaming-snake-case.d.ts +30 -0
- package/source/set-field-type.d.ts +67 -0
- package/source/set-non-nullable-deep.d.ts +85 -0
- package/source/set-non-nullable.d.ts +41 -0
- package/source/set-optional.d.ts +46 -0
- package/source/set-parameter-type.d.ts +125 -0
- package/source/set-readonly.d.ts +44 -0
- package/source/set-required-deep.d.ts +64 -0
- package/source/set-required.d.ts +79 -0
- package/source/set-return-type.d.ts +31 -0
- package/source/shared-union-fields-deep.d.ts +180 -0
- package/source/shared-union-fields.d.ts +79 -0
- package/source/simplify-deep.d.ts +117 -0
- package/source/simplify.d.ts +61 -0
- package/source/single-key-object.d.ts +28 -0
- package/source/snake-case.d.ts +47 -0
- package/source/snake-cased-properties-deep.d.ts +65 -0
- package/source/snake-cased-properties.d.ts +42 -0
- package/source/split-on-rest-element.d.ts +106 -0
- package/source/split.d.ts +90 -0
- package/source/spread.d.ts +82 -0
- package/source/string-repeat.d.ts +49 -0
- package/source/string-slice.d.ts +39 -0
- package/source/stringified.d.ts +25 -0
- package/source/structured-cloneable.d.ts +89 -0
- package/source/subtract.d.ts +86 -0
- package/source/sum.d.ts +81 -0
- package/source/tagged-union.d.ts +53 -0
- package/source/tagged.d.ts +263 -0
- package/source/trim.d.ts +29 -0
- package/source/tsconfig-json.d.ts +1324 -0
- package/source/tuple-of.d.ts +80 -0
- package/source/tuple-to-object.d.ts +47 -0
- package/source/tuple-to-union.d.ts +54 -0
- package/source/typed-array.d.ts +19 -0
- package/source/undefined-on-partial-deep.d.ts +83 -0
- package/source/union-to-intersection.d.ts +35 -0
- package/source/union-to-tuple.d.ts +58 -0
- package/source/unknown-array.d.ts +27 -0
- package/source/unknown-map.d.ts +26 -0
- package/source/unknown-record.d.ts +33 -0
- package/source/unknown-set.d.ts +26 -0
- package/source/unwrap-partial.d.ts +33 -0
- package/source/value-of.d.ts +24 -0
- package/source/words.d.ts +122 -0
- package/source/writable-deep.d.ts +84 -0
- package/source/writable-keys-of.d.ts +34 -0
- package/source/writable.d.ts +72 -0
- package/source/xor.d.ts +83 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type {KeysOfUnion} from './keys-of-union.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Pick keys from a type, distributing the operation over a union.
|
|
5
|
+
|
|
6
|
+
TypeScript's `Pick` doesn't distribute over unions, leading to the erasure of unique properties from union members when picking keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Pick. Essentially, using `Pick` on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that.
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
type A = {
|
|
12
|
+
discriminant: 'A';
|
|
13
|
+
foo: {
|
|
14
|
+
bar: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type B = {
|
|
19
|
+
discriminant: 'B';
|
|
20
|
+
foo: {
|
|
21
|
+
baz: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type Union = A | B;
|
|
26
|
+
|
|
27
|
+
type PickedUnion = Pick<Union, 'discriminant' | 'foo'>;
|
|
28
|
+
//=> {discriminant: 'A' | 'B'; foo: {bar: string} | {baz: string}}
|
|
29
|
+
|
|
30
|
+
declare const pickedUnion: PickedUnion;
|
|
31
|
+
|
|
32
|
+
if (pickedUnion.discriminant === 'A') {
|
|
33
|
+
// We would like to narrow `pickedUnion`'s type
|
|
34
|
+
// to `A` here, but we can't because `Pick`
|
|
35
|
+
// doesn't distribute over unions.
|
|
36
|
+
|
|
37
|
+
// @ts-expect-error
|
|
38
|
+
const barValue = pickedUnion.foo.bar;
|
|
39
|
+
// Error: Property 'bar' does not exist on type '{bar: string} | {baz: string}'.
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
@example
|
|
44
|
+
```
|
|
45
|
+
import type {DistributedPick} from 'type-fest';
|
|
46
|
+
|
|
47
|
+
type A = {
|
|
48
|
+
discriminant: 'A';
|
|
49
|
+
foo: {
|
|
50
|
+
bar: string;
|
|
51
|
+
};
|
|
52
|
+
extraneous: boolean;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
type B = {
|
|
56
|
+
discriminant: 'B';
|
|
57
|
+
foo: {
|
|
58
|
+
baz: string;
|
|
59
|
+
};
|
|
60
|
+
extraneous: boolean;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Notice that `foo.bar` exists in `A` but not in `B`.
|
|
64
|
+
|
|
65
|
+
type Union = A | B;
|
|
66
|
+
|
|
67
|
+
type PickedUnion = DistributedPick<Union, 'discriminant' | 'foo'>;
|
|
68
|
+
|
|
69
|
+
declare const pickedUnion: PickedUnion;
|
|
70
|
+
|
|
71
|
+
if (pickedUnion.discriminant === 'A') {
|
|
72
|
+
const barValue = pickedUnion.foo.bar;
|
|
73
|
+
// OK
|
|
74
|
+
|
|
75
|
+
// @ts-expect-error
|
|
76
|
+
const extraneousValue = pickedUnion.extraneous;
|
|
77
|
+
// Error: Property `extraneous` does not exist on type `Pick<A, 'discriminant' | 'foo'>`.
|
|
78
|
+
|
|
79
|
+
// @ts-expect-error
|
|
80
|
+
const bazValue = pickedUnion.foo.baz;
|
|
81
|
+
// Error: `bar` is not a property of `{discriminant: 'A'; a: string}`.
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
@category Object
|
|
86
|
+
*/
|
|
87
|
+
export type DistributedPick<ObjectType, KeyType extends KeysOfUnion<ObjectType>> =
|
|
88
|
+
ObjectType extends unknown
|
|
89
|
+
? Pick<ObjectType, Extract<KeyType, keyof ObjectType>>
|
|
90
|
+
: never;
|
|
91
|
+
|
|
92
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
declare const emptyObjectSymbol: unique symbol;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Represents a strictly empty plain object, the `{}` value.
|
|
5
|
+
|
|
6
|
+
When you annotate something as the type `{}`, it can be anything except `null` and `undefined`. This means that you cannot use `{}` to represent an empty plain object ([read more](https://stackoverflow.com/questions/47339869/typescript-empty-object-and-any-difference/52193484#52193484)).
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {EmptyObject} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
// The following illustrates the problem with `{}`.
|
|
13
|
+
const foo1: {} = {}; // Pass
|
|
14
|
+
const foo2: {} = []; // Pass
|
|
15
|
+
const foo3: {} = 42; // Pass
|
|
16
|
+
const foo4: {} = {a: 1}; // Pass
|
|
17
|
+
|
|
18
|
+
// With `EmptyObject` only the first case is valid.
|
|
19
|
+
const bar1: EmptyObject = {}; // Pass
|
|
20
|
+
// @ts-expect-error
|
|
21
|
+
const bar2: EmptyObject = []; // Fail
|
|
22
|
+
// @ts-expect-error
|
|
23
|
+
const bar3: EmptyObject = 42; // Fail
|
|
24
|
+
// @ts-expect-error
|
|
25
|
+
const bar4: EmptyObject = {a: 1}; // Fail
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<never, never>` do not work. See {@link https://github.com/sindresorhus/type-fest/issues/395 #395}.
|
|
29
|
+
|
|
30
|
+
@category Object
|
|
31
|
+
*/
|
|
32
|
+
export type EmptyObject = {[emptyObjectSymbol]?: never};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
Returns a `boolean` for whether the type is strictly equal to an empty plain object, the `{}` value.
|
|
36
|
+
|
|
37
|
+
@example
|
|
38
|
+
```
|
|
39
|
+
import type {IsEmptyObject} from 'type-fest';
|
|
40
|
+
|
|
41
|
+
type Pass = IsEmptyObject<{}>; //=> true
|
|
42
|
+
type Fail1 = IsEmptyObject<[]>; //=> false
|
|
43
|
+
type Fail2 = IsEmptyObject<null>; //=> false
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
@see {@link EmptyObject}
|
|
47
|
+
@category Object
|
|
48
|
+
*/
|
|
49
|
+
export type IsEmptyObject<T> = T extends EmptyObject ? true : false;
|
|
50
|
+
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type {_ArrayEntry, _MapEntry, _ObjectEntry, _SetEntry} from './entry.d.ts';
|
|
2
|
+
|
|
3
|
+
type ArrayEntries<BaseType extends readonly unknown[]> = Array<_ArrayEntry<BaseType>>;
|
|
4
|
+
type MapEntries<BaseType> = Array<_MapEntry<BaseType>>;
|
|
5
|
+
type ObjectEntries<BaseType> = Array<_ObjectEntry<BaseType>>;
|
|
6
|
+
type SetEntries<BaseType extends Set<unknown>> = Array<_SetEntry<BaseType>>;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entries` type will return the type of that collection's entries.
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
@see `Entry` if you want to just access the type of a single entry.
|
|
14
|
+
|
|
15
|
+
@example
|
|
16
|
+
```
|
|
17
|
+
import type {Entries} from 'type-fest';
|
|
18
|
+
|
|
19
|
+
type Example = {
|
|
20
|
+
someKey: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const manipulatesEntries = (examples: Entries<Example>) => examples.map(example => [
|
|
24
|
+
// Does some arbitrary processing on the key (with type information available)
|
|
25
|
+
example[0].toUpperCase(),
|
|
26
|
+
|
|
27
|
+
// Does some arbitrary processing on the value (with type information available)
|
|
28
|
+
example[1].toFixed(0),
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const example: Example = {someKey: 1};
|
|
32
|
+
const entries = Object.entries(example) as Entries<Example>;
|
|
33
|
+
const output = manipulatesEntries(entries);
|
|
34
|
+
|
|
35
|
+
// Objects
|
|
36
|
+
const objectExample = {a: 1};
|
|
37
|
+
const objectEntries: Entries<typeof objectExample> = [['a', 1]];
|
|
38
|
+
|
|
39
|
+
// Arrays
|
|
40
|
+
const arrayExample = ['a', 1];
|
|
41
|
+
const arrayEntries: Entries<typeof arrayExample> = [[0, 'a'], [1, 1]];
|
|
42
|
+
|
|
43
|
+
// Maps
|
|
44
|
+
const mapExample = new Map([['a', 1]]);
|
|
45
|
+
const mapEntries: Entries<typeof mapExample> = [['a', 1]];
|
|
46
|
+
|
|
47
|
+
// Sets
|
|
48
|
+
const setExample = new Set(['a', 1]);
|
|
49
|
+
const setEntries: Entries<typeof setExample> = [['a', 'a'], [1, 1]];
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
@category Object
|
|
53
|
+
@category Map
|
|
54
|
+
@category Set
|
|
55
|
+
@category Array
|
|
56
|
+
*/
|
|
57
|
+
export type Entries<BaseType> =
|
|
58
|
+
BaseType extends Map<unknown, unknown> ? MapEntries<BaseType>
|
|
59
|
+
: BaseType extends Set<unknown> ? SetEntries<BaseType>
|
|
60
|
+
: BaseType extends readonly unknown[] ? ArrayEntries<BaseType>
|
|
61
|
+
: BaseType extends object ? ObjectEntries<BaseType>
|
|
62
|
+
: never;
|
|
63
|
+
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
type 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(0),
|
|
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;
|
|
66
|
+
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type {ObjectValue} from './internal/index.d.ts';
|
|
2
|
+
import type {ArrayElement} from './array-element.d.ts';
|
|
3
|
+
import type {IsEqual} from './is-equal.d.ts';
|
|
4
|
+
import type {KeysOfUnion} from './keys-of-union.d.ts';
|
|
5
|
+
import type {IsUnknown} from './is-unknown.d.ts';
|
|
6
|
+
import type {Primitive} from './primitive.d.ts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`.
|
|
10
|
+
- Generate a list of keys that exists in `InputType` but not in `ParameterType`.
|
|
11
|
+
- Mark these excess keys as `never`.
|
|
12
|
+
*/
|
|
13
|
+
type ExactObject<ParameterType, InputType> = {[Key in keyof ParameterType]: Exact<ParameterType[Key], ObjectValue<InputType, Key>>}
|
|
14
|
+
& Record<Exclude<keyof InputType, KeysOfUnion<ParameterType>>, never>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared.
|
|
18
|
+
|
|
19
|
+
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.
|
|
20
|
+
|
|
21
|
+
*Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/12936) if you want to have this type as a built-in in TypeScript.*
|
|
22
|
+
|
|
23
|
+
@example
|
|
24
|
+
```
|
|
25
|
+
type OnlyAcceptName = {name: string};
|
|
26
|
+
|
|
27
|
+
declare function onlyAcceptName(arguments_: OnlyAcceptName): void;
|
|
28
|
+
|
|
29
|
+
// TypeScript complains about excess properties when an object literal is provided.
|
|
30
|
+
// @ts-expect-error
|
|
31
|
+
onlyAcceptName({name: 'name', id: 1});
|
|
32
|
+
// `id` is excess
|
|
33
|
+
|
|
34
|
+
// TypeScript does not complain about excess properties when the provided value is a variable (not an object literal).
|
|
35
|
+
const invalidInput = {name: 'name', id: 1};
|
|
36
|
+
onlyAcceptName(invalidInput); // No errors
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Having `Exact` allows TypeScript to reject excess properties.
|
|
40
|
+
|
|
41
|
+
@example
|
|
42
|
+
```
|
|
43
|
+
import type {Exact} from 'type-fest';
|
|
44
|
+
|
|
45
|
+
type OnlyAcceptName = {name: string};
|
|
46
|
+
|
|
47
|
+
declare function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(arguments_: T): void;
|
|
48
|
+
|
|
49
|
+
const invalidInput = {name: 'name', id: 1};
|
|
50
|
+
// @ts-expect-error
|
|
51
|
+
onlyAcceptNameImproved(invalidInput); // Compilation error
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
[Read more](https://stackoverflow.com/questions/49580725/is-it-possible-to-restrict-typescript-object-to-contain-only-properties-defined)
|
|
55
|
+
|
|
56
|
+
@category Utilities
|
|
57
|
+
*/
|
|
58
|
+
export type Exact<ParameterType, InputType> =
|
|
59
|
+
// Before distributing, check if the two types are equal and if so, return the parameter type immediately
|
|
60
|
+
IsEqual<ParameterType, InputType> extends true ? ParameterType
|
|
61
|
+
// If the parameter is a primitive, return it as is immediately to avoid it being converted to a complex type
|
|
62
|
+
: ParameterType extends Primitive ? ParameterType
|
|
63
|
+
// If the parameter is an unknown, return it as is immediately to avoid it being converted to a complex type
|
|
64
|
+
: IsUnknown<ParameterType> extends true ? unknown
|
|
65
|
+
// If the parameter is a Function, return it as is because this type is not capable of handling function, leave it to TypeScript
|
|
66
|
+
: ParameterType extends Function ? ParameterType
|
|
67
|
+
// Convert union of array to array of union: A[] & B[] => (A & B)[]
|
|
68
|
+
: ParameterType extends unknown[] ? Array<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
69
|
+
// In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray.
|
|
70
|
+
: ParameterType extends readonly unknown[] ? ReadonlyArray<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
71
|
+
: ExactObject<ParameterType, InputType>;
|
|
72
|
+
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
2
|
+
import type {IsEqual} from './is-equal.d.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Filter out keys from an object.
|
|
6
|
+
|
|
7
|
+
Returns `never` if `Exclude` is strictly equal to `Key`.
|
|
8
|
+
Returns `never` if `Key` extends `Exclude`.
|
|
9
|
+
Returns `Key` otherwise.
|
|
10
|
+
|
|
11
|
+
@example
|
|
12
|
+
```
|
|
13
|
+
type Filtered = Filter<'foo', 'foo'>;
|
|
14
|
+
//=> never
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
@example
|
|
18
|
+
```
|
|
19
|
+
type Filtered = Filter<'bar', string>;
|
|
20
|
+
//=> never
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
@example
|
|
24
|
+
```
|
|
25
|
+
type Filtered = Filter<'bar', 'foo'>;
|
|
26
|
+
//=> 'bar'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
@see {Except}
|
|
30
|
+
*/
|
|
31
|
+
type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType);
|
|
32
|
+
|
|
33
|
+
export type ExceptOptions = {
|
|
34
|
+
/**
|
|
35
|
+
Disallow assigning non-specified properties.
|
|
36
|
+
|
|
37
|
+
Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`.
|
|
38
|
+
|
|
39
|
+
@default false
|
|
40
|
+
*/
|
|
41
|
+
requireExactProps?: boolean;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type DefaultExceptOptions = {
|
|
45
|
+
requireExactProps: false;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
Create a type from an object type without certain keys.
|
|
50
|
+
|
|
51
|
+
We recommend setting the `requireExactProps` option to `true`.
|
|
52
|
+
|
|
53
|
+
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.
|
|
54
|
+
|
|
55
|
+
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)).
|
|
56
|
+
|
|
57
|
+
@example
|
|
58
|
+
```
|
|
59
|
+
import type {Except} from 'type-fest';
|
|
60
|
+
|
|
61
|
+
type Foo = {
|
|
62
|
+
a: number;
|
|
63
|
+
b: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type FooWithoutA = Except<Foo, 'a'>;
|
|
67
|
+
//=> {b: string}
|
|
68
|
+
|
|
69
|
+
// @ts-expect-error
|
|
70
|
+
const fooWithoutA: FooWithoutA = {a: 1, b: '2'};
|
|
71
|
+
// errors: 'a' does not exist in type '{ b: string; }'
|
|
72
|
+
|
|
73
|
+
type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>;
|
|
74
|
+
//=> {a: number} & Partial<Record<'b', never>>
|
|
75
|
+
|
|
76
|
+
// @ts-expect-error
|
|
77
|
+
const fooWithoutB: FooWithoutB = {a: 1, b: '2'};
|
|
78
|
+
// errors at 'b': Type 'string' is not assignable to type 'undefined'.
|
|
79
|
+
|
|
80
|
+
// The `Omit` utility type doesn't work when omitting specific keys from objects containing index signatures.
|
|
81
|
+
|
|
82
|
+
// Consider the following example:
|
|
83
|
+
|
|
84
|
+
type UserData = {
|
|
85
|
+
[metadata: string]: string;
|
|
86
|
+
email: string;
|
|
87
|
+
name: string;
|
|
88
|
+
role: 'admin' | 'user';
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// `Omit` clearly doesn't behave as expected in this case:
|
|
92
|
+
type PostPayload = Omit<UserData, 'email'>;
|
|
93
|
+
//=> {[x: string]: string; [x: number]: string}
|
|
94
|
+
|
|
95
|
+
// In situations like this, `Except` works better.
|
|
96
|
+
// It simply removes the `email` key while preserving all the other keys.
|
|
97
|
+
type PostPayloadFixed = Except<UserData, 'email'>;
|
|
98
|
+
//=> {[x: string]: string; name: string; role: 'admin' | 'user'}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
@category Object
|
|
102
|
+
*/
|
|
103
|
+
export type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {}> =
|
|
104
|
+
_Except<ObjectType, KeysType, ApplyDefaultOptions<ExceptOptions, DefaultExceptOptions, Options>>;
|
|
105
|
+
|
|
106
|
+
type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = {
|
|
107
|
+
[KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
|
|
108
|
+
} & (Options['requireExactProps'] extends true
|
|
109
|
+
? Partial<Record<KeysType, never>>
|
|
110
|
+
: {});
|
|
111
|
+
|
|
112
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type {SplitOnRestElement} from './split-on-rest-element.d.ts';
|
|
2
|
+
import type {IsArrayReadonly} from './internal/array.d.ts';
|
|
3
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
4
|
+
import type {IfNotAnyOrNever} from './internal/type.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Create a tuple with the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element removed.
|
|
8
|
+
|
|
9
|
+
@example
|
|
10
|
+
```
|
|
11
|
+
import type {ExcludeRestElement} from 'type-fest';
|
|
12
|
+
|
|
13
|
+
type T1 = ExcludeRestElement<[number, ...string[], string, 'foo']>;
|
|
14
|
+
//=> [number, string, 'foo']
|
|
15
|
+
|
|
16
|
+
type T2 = ExcludeRestElement<[...boolean[], string]>;
|
|
17
|
+
//=> [string]
|
|
18
|
+
|
|
19
|
+
type T3 = ExcludeRestElement<[...Array<'foo'>, true]>;
|
|
20
|
+
//=> [true]
|
|
21
|
+
|
|
22
|
+
type T4 = ExcludeRestElement<[number, string]>;
|
|
23
|
+
//=> [number, string]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
@see {@link ExtractRestElement}
|
|
27
|
+
@see {@link SplitOnRestElement}
|
|
28
|
+
@category Array
|
|
29
|
+
*/
|
|
30
|
+
export type ExcludeRestElement<Array_ extends UnknownArray> = IfNotAnyOrNever<Array_,
|
|
31
|
+
SplitOnRestElement<Array_> extends infer Result
|
|
32
|
+
? Result extends readonly UnknownArray[]
|
|
33
|
+
? IsArrayReadonly<Array_> extends true
|
|
34
|
+
? Readonly<[...Result[0], ...Result[2]]>
|
|
35
|
+
: [...Result[0], ...Result[2]]
|
|
36
|
+
: never
|
|
37
|
+
: never
|
|
38
|
+
>;
|
|
39
|
+
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
A stricter version of {@link Exclude<T, U>} that ensures every member of `U` can successfully exclude something from `T`.
|
|
3
|
+
|
|
4
|
+
For example, `ExcludeStrict<string | number | boolean, number | bigint>` will error because `bigint` cannot exclude anything from `string | number | boolean`.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
// Valid Examples
|
|
9
|
+
import type {ExcludeStrict} from 'type-fest';
|
|
10
|
+
|
|
11
|
+
type Example1 = ExcludeStrict<{status: 'success'; data: string[]} | {status: 'error'; error: string}, {status: 'success'}>;
|
|
12
|
+
//=> {status: 'error'; error: string}
|
|
13
|
+
|
|
14
|
+
type Example2 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xs' | 's'>;
|
|
15
|
+
//=> 'm' | 'l' | 'xl'
|
|
16
|
+
|
|
17
|
+
type Example3 = ExcludeStrict<{x: number; y: number} | [number, number], unknown[]>;
|
|
18
|
+
//=> {x: number; y: number}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
@example
|
|
22
|
+
```
|
|
23
|
+
// Invalid Examples
|
|
24
|
+
import type {ExcludeStrict} from 'type-fest';
|
|
25
|
+
|
|
26
|
+
// `'xxl'` cannot exclude anything from `'xs' | 's' | 'm' | 'l' | 'xl'`
|
|
27
|
+
// @ts-expect-error
|
|
28
|
+
type Example1 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xl' | 'xxl'>;
|
|
29
|
+
// ~~~~~~~~~~~~
|
|
30
|
+
// Error: Type "'xl' | 'xxl'" does not satisfy the constraint 'never'.
|
|
31
|
+
|
|
32
|
+
// `unknown[]` cannot exclude anything from `{x: number; y: number} | {x: string; y: string}`
|
|
33
|
+
// @ts-expect-error
|
|
34
|
+
type Example2 = ExcludeStrict<{x: number; y: number} | {x: string; y: string}, unknown[]>;
|
|
35
|
+
// ~~~~~~~~~
|
|
36
|
+
// Error: Type 'unknown[]' does not satisfy the constraint 'never'.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
@category Improved Built-in
|
|
40
|
+
*/
|
|
41
|
+
export type ExcludeStrict<
|
|
42
|
+
T,
|
|
43
|
+
U extends [U] extends [
|
|
44
|
+
// Ensure every member of `U` excludes something from `T`
|
|
45
|
+
U extends unknown ? ([T] extends [Exclude<T, U>] ? never : U) : never,
|
|
46
|
+
]
|
|
47
|
+
? unknown
|
|
48
|
+
: never,
|
|
49
|
+
> = Exclude<T, U>;
|
|
50
|
+
|
|
51
|
+
export {};
|