type-fest 5.1.0 → 5.3.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/index.d.ts +4 -0
- package/package.json +7 -2
- package/readme.md +3 -1
- package/source/all-union-fields.d.ts +9 -8
- package/source/and.d.ts +2 -0
- package/source/array-element.d.ts +46 -0
- package/source/array-slice.d.ts +29 -8
- package/source/array-splice.d.ts +8 -6
- package/source/arrayable.d.ts +2 -2
- package/source/async-return-type.d.ts +6 -3
- package/source/asyncify.d.ts +7 -16
- package/source/camel-case.d.ts +7 -6
- package/source/camel-cased-properties-deep.d.ts +6 -6
- package/source/camel-cased-properties.d.ts +4 -4
- package/source/characters.d.ts +8 -3
- package/source/conditional-except.d.ts +6 -6
- package/source/conditional-pick-deep.d.ts +4 -4
- package/source/conditional-pick.d.ts +6 -6
- package/source/conditional-simplify-deep.d.ts +1 -1
- package/source/conditional-simplify.d.ts +1 -1
- package/source/delimiter-case.d.ts +5 -5
- package/source/delimiter-cased-properties-deep.d.ts +8 -8
- package/source/delimiter-cased-properties.d.ts +4 -4
- package/source/distributed-omit.d.ts +15 -10
- package/source/distributed-pick.d.ts +12 -7
- package/source/empty-object.d.ts +8 -5
- package/source/entries.d.ts +3 -3
- package/source/entry.d.ts +3 -3
- package/source/exact.d.ts +7 -4
- package/source/except.d.ts +5 -3
- package/source/exclude-rest-element.d.ts +8 -5
- package/source/exclude-strict.d.ts +4 -0
- package/source/exclusify-union.d.ts +113 -0
- package/source/extract-rest-element.d.ts +3 -2
- package/source/extract-strict.d.ts +5 -1
- package/source/find-global-type.d.ts +7 -5
- package/source/fixed-length-array.d.ts +8 -0
- package/source/get.d.ts +27 -28
- package/source/global-this.d.ts +2 -1
- package/source/greater-than-or-equal.d.ts +10 -4
- package/source/greater-than.d.ts +3 -3
- package/source/has-optional-keys.d.ts +2 -2
- package/source/has-readonly-keys.d.ts +2 -2
- package/source/has-required-keys.d.ts +10 -10
- package/source/has-writable-keys.d.ts +2 -2
- package/source/if.d.ts +38 -3
- package/source/int-closed-range.d.ts +18 -8
- package/source/int-range.d.ts +18 -8
- package/source/internal/array.d.ts +4 -13
- package/source/internal/numeric.d.ts +7 -7
- package/source/internal/object.d.ts +13 -12
- package/source/internal/string.d.ts +15 -15
- package/source/internal/tuple.d.ts +5 -5
- package/source/internal/type.d.ts +38 -6
- package/source/invariant-of.d.ts +26 -19
- package/source/is-any.d.ts +2 -2
- package/source/is-equal.d.ts +4 -8
- package/source/is-integer.d.ts +1 -1
- package/source/is-literal.d.ts +13 -13
- package/source/is-lowercase.d.ts +3 -3
- package/source/is-never.d.ts +35 -23
- package/source/is-null.d.ts +1 -1
- package/source/is-optional-key-of.d.ts +4 -4
- package/source/is-readonly-key-of.d.ts +4 -4
- package/source/is-required-key-of.d.ts +4 -4
- package/source/is-unknown.d.ts +12 -23
- package/source/is-uppercase.d.ts +3 -3
- package/source/is-writable-key-of.d.ts +4 -4
- package/source/iterable-element.d.ts +3 -3
- package/source/join.d.ts +27 -18
- package/source/jsonifiable.d.ts +5 -5
- package/source/jsonify.d.ts +7 -8
- package/source/kebab-case.d.ts +3 -3
- package/source/kebab-cased-properties-deep.d.ts +8 -8
- package/source/kebab-cased-properties.d.ts +4 -4
- package/source/last-array-element.d.ts +5 -9
- package/source/less-than-or-equal.d.ts +3 -3
- package/source/less-than.d.ts +3 -3
- package/source/literal-to-primitive-deep.d.ts +41 -8
- package/source/literal-union.d.ts +2 -2
- package/source/merge-deep.d.ts +6 -8
- package/source/merge-exclusive.d.ts +7 -4
- package/source/merge.d.ts +2 -2
- package/source/multidimensional-array.d.ts +7 -15
- package/source/multidimensional-readonly-array.d.ts +7 -19
- package/source/non-empty-object.d.ts +1 -0
- package/source/non-empty-string.d.ts +3 -1
- package/source/non-empty-tuple.d.ts +1 -0
- package/source/numeric.d.ts +22 -20
- package/source/omit-deep.d.ts +13 -12
- package/source/omit-index-signature.d.ts +18 -21
- package/source/optional-keys-of.d.ts +4 -4
- package/source/or.d.ts +7 -5
- package/source/override-properties.d.ts +11 -6
- package/source/package-json.d.ts +32 -0
- package/source/partial-on-undefined-deep.d.ts +3 -3
- package/source/pascal-case.d.ts +1 -1
- package/source/pascal-cased-properties-deep.d.ts +6 -6
- package/source/pascal-cased-properties.d.ts +4 -4
- package/source/paths.d.ts +12 -0
- package/source/pick-deep.d.ts +2 -2
- package/source/pick-index-signature.d.ts +1 -1
- package/source/promisable.d.ts +2 -2
- package/source/readonly-deep.d.ts +45 -12
- package/source/readonly-keys-of.d.ts +3 -3
- package/source/readonly-tuple.d.ts +5 -3
- package/source/remove-prefix.d.ts +2 -0
- package/source/replace.d.ts +3 -3
- package/source/require-all-or-none.d.ts +2 -2
- package/source/require-at-least-one.d.ts +1 -1
- package/source/require-exactly-one.d.ts +1 -1
- package/source/require-one-or-none.d.ts +3 -3
- package/source/required-keys-of.d.ts +10 -4
- package/source/set-field-type.d.ts +2 -2
- package/source/set-non-nullable.d.ts +1 -1
- package/source/set-optional.d.ts +1 -1
- package/source/set-parameter-type.d.ts +12 -6
- package/source/set-readonly.d.ts +1 -1
- package/source/set-required-deep.d.ts +4 -4
- package/source/set-required.d.ts +1 -1
- package/source/set-return-type.d.ts +3 -3
- package/source/shared-union-fields-deep.d.ts +6 -6
- package/source/shared-union-fields.d.ts +7 -7
- package/source/simplify-deep.d.ts +3 -4
- package/source/simplify.d.ts +3 -2
- package/source/single-key-object.d.ts +4 -8
- package/source/snake-case.d.ts +3 -3
- package/source/snake-cased-properties-deep.d.ts +7 -7
- package/source/snake-cased-properties.d.ts +4 -4
- package/source/split-on-rest-element.d.ts +2 -2
- package/source/split.d.ts +4 -4
- package/source/spread.d.ts +2 -6
- package/source/string-repeat.d.ts +2 -2
- package/source/string-slice.d.ts +6 -6
- package/source/stringified.d.ts +2 -2
- package/source/structured-cloneable.d.ts +11 -16
- package/source/subtract.d.ts +7 -7
- package/source/sum.d.ts +6 -6
- package/source/tagged-union.d.ts +2 -2
- package/source/tagged.d.ts +15 -13
- package/source/trim.d.ts +1 -1
- package/source/tuple-of.d.ts +2 -0
- package/source/tuple-to-object.d.ts +2 -0
- package/source/tuple-to-union.d.ts +3 -2
- package/source/undefined-on-partial-deep.d.ts +5 -4
- package/source/union-to-intersection.d.ts +0 -28
- package/source/union-to-tuple.d.ts +3 -3
- package/source/value-of.d.ts +6 -26
- package/source/words.d.ts +2 -0
- package/source/writable-deep.d.ts +1 -1
- package/source/writable-keys-of.d.ts +2 -2
- package/source/writable.d.ts +2 -0
package/source/tagged.d.ts
CHANGED
|
@@ -38,15 +38,14 @@ function createAccountNumber(): AccountNumber {
|
|
|
38
38
|
return 2 as AccountNumber;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance
|
|
42
|
-
return 4 as AccountBalance;
|
|
43
|
-
}
|
|
41
|
+
declare function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance;
|
|
44
42
|
|
|
45
43
|
// This will compile successfully.
|
|
46
44
|
getMoneyForAccount(createAccountNumber());
|
|
47
45
|
|
|
48
46
|
// But this won't, because it has to be explicitly passed as an `AccountNumber` type!
|
|
49
47
|
// Critically, you could not accidentally use an `AccountBalance` as an `AccountNumber`.
|
|
48
|
+
// @ts-expect-error
|
|
50
49
|
getMoneyForAccount(2);
|
|
51
50
|
|
|
52
51
|
// You can also use tagged values like their underlying, untagged type.
|
|
@@ -80,19 +79,19 @@ This article explains more about [how tag metadata works and when it can be usef
|
|
|
80
79
|
|
|
81
80
|
@example
|
|
82
81
|
```
|
|
83
|
-
import type {Tagged} from 'type-fest';
|
|
82
|
+
import type {Tagged, GetTagMetadata} from 'type-fest';
|
|
84
83
|
|
|
85
84
|
type JsonOf<T> = Tagged<string, 'JSON', T>;
|
|
86
85
|
|
|
87
86
|
function stringify<T>(it: T) {
|
|
88
|
-
|
|
87
|
+
return JSON.stringify(it) as JsonOf<T>;
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
function parse<T extends JsonOf<unknown>>(it: T) {
|
|
92
|
-
|
|
91
|
+
return JSON.parse(it) as GetTagMetadata<T, 'JSON'>;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
const x = stringify({
|
|
94
|
+
const x = stringify({hello: 'world'});
|
|
96
95
|
const parsed = parse(x); // The type of `parsed` is { hello: string }
|
|
97
96
|
```
|
|
98
97
|
|
|
@@ -116,13 +115,14 @@ type AccountType = Tagged<'SAVINGS' | 'CHECKING', 'AccountType'>;
|
|
|
116
115
|
|
|
117
116
|
const moneyByAccountType: Record<UnwrapTagged<AccountType>, number> = {
|
|
118
117
|
SAVINGS: 99,
|
|
119
|
-
CHECKING: 0.1
|
|
118
|
+
CHECKING: 0.1,
|
|
120
119
|
};
|
|
121
120
|
|
|
122
121
|
// Without UnwrapTagged, the following expression would throw a type error.
|
|
123
122
|
const money = moneyByAccountType.SAVINGS; // TS error: Property 'SAVINGS' does not exist
|
|
124
123
|
|
|
125
124
|
// Attempting to pass an non-Tagged type to UnwrapTagged will raise a type error.
|
|
125
|
+
// @ts-expect-error
|
|
126
126
|
type WontWork = UnwrapTagged<string>;
|
|
127
127
|
```
|
|
128
128
|
|
|
@@ -174,12 +174,13 @@ type NewThingOne = Opaque<string, 'ThingOne'>;
|
|
|
174
174
|
type NewThingTwo = Opaque<string, 'ThingTwo'>;
|
|
175
175
|
|
|
176
176
|
// Now they're completely separate types, so the following will fail to compile.
|
|
177
|
-
function createNewThingOne
|
|
177
|
+
function createNewThingOne(): NewThingOne {
|
|
178
178
|
// As you can see, casting from a string is still allowed. However, you may not cast NewThingOne to NewThingTwo, and vice versa.
|
|
179
179
|
return 'new thing one' as NewThingOne;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
// This will fail to compile, as they are fundamentally different types.
|
|
183
|
+
// @ts-expect-error
|
|
183
184
|
const thingTwo = createNewThingOne() as NewThingTwo;
|
|
184
185
|
|
|
185
186
|
// Here's another example of opaque typing.
|
|
@@ -187,14 +188,13 @@ function createAccountNumber(): AccountNumber {
|
|
|
187
188
|
return 2 as AccountNumber;
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance
|
|
191
|
-
return 4 as AccountBalance;
|
|
192
|
-
}
|
|
191
|
+
declare function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance;
|
|
193
192
|
|
|
194
193
|
// This will compile successfully.
|
|
195
194
|
getMoneyForAccount(createAccountNumber());
|
|
196
195
|
|
|
197
196
|
// But this won't, because it has to be explicitly passed as an `AccountNumber` type.
|
|
197
|
+
// @ts-expect-error
|
|
198
198
|
getMoneyForAccount(2);
|
|
199
199
|
|
|
200
200
|
// You can use opaque values like they aren't opaque too.
|
|
@@ -233,16 +233,18 @@ type AccountType = Opaque<'SAVINGS' | 'CHECKING', 'AccountType'>;
|
|
|
233
233
|
|
|
234
234
|
const moneyByAccountType: Record<UnwrapOpaque<AccountType>, number> = {
|
|
235
235
|
SAVINGS: 99,
|
|
236
|
-
CHECKING: 0.1
|
|
236
|
+
CHECKING: 0.1,
|
|
237
237
|
};
|
|
238
238
|
|
|
239
239
|
// Without UnwrapOpaque, the following expression would throw a type error.
|
|
240
240
|
const money = moneyByAccountType.SAVINGS; // TS error: Property 'SAVINGS' does not exist
|
|
241
241
|
|
|
242
242
|
// Attempting to pass an non-Opaque type to UnwrapOpaque will raise a type error.
|
|
243
|
+
// @ts-expect-error
|
|
243
244
|
type WontWork = UnwrapOpaque<string>;
|
|
244
245
|
|
|
245
246
|
// Using a Tagged type will work too.
|
|
247
|
+
// @ts-expect-error
|
|
246
248
|
type WillWork = UnwrapOpaque<Tagged<number, 'AccountNumber'>>; // number
|
|
247
249
|
```
|
|
248
250
|
|
package/source/trim.d.ts
CHANGED
package/source/tuple-of.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ type TicTacToeBoard = TupleOf<3, TupleOf<3, 'X' | 'O' | null>>;
|
|
|
22
22
|
|
|
23
23
|
@example
|
|
24
24
|
```
|
|
25
|
+
import type {TupleOf} from 'type-fest';
|
|
26
|
+
|
|
25
27
|
type Range<Start extends number, End extends number> = Exclude<keyof TupleOf<End>, keyof TupleOf<Start>>;
|
|
26
28
|
|
|
27
29
|
type ZeroToFour = Range<0, 5>;
|
|
@@ -10,6 +10,8 @@ Note: Tuple labels are [lost in the transformation process](https://stackoverflo
|
|
|
10
10
|
|
|
11
11
|
@example
|
|
12
12
|
```
|
|
13
|
+
import type {TupleToObject} from 'type-fest';
|
|
14
|
+
|
|
13
15
|
type Example1 = TupleToObject<[number, string, boolean]>;
|
|
14
16
|
//=> { 0: number; 1: string; 2: boolean }
|
|
15
17
|
|
|
@@ -21,7 +21,7 @@ type RequestBody = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
function verifyRequestBody(body: unknown): body is RequestBody {
|
|
24
|
-
const deliverTo = (body as any)
|
|
24
|
+
const {deliverTo} = (body as any);
|
|
25
25
|
return typeof body === 'object' && body !== null && verifyDestination(deliverTo);
|
|
26
26
|
}
|
|
27
27
|
```
|
|
@@ -37,10 +37,11 @@ type Destination = typeof destinations[number];
|
|
|
37
37
|
|
|
38
38
|
const erroringType = new Set(['a', 'b', 'c']);
|
|
39
39
|
|
|
40
|
+
// @ts-expect-error
|
|
40
41
|
type ErroringType = typeof erroringType[number];
|
|
41
42
|
//=> Type 'Set<string>' has no matching index signature for type 'number'. ts(2537)
|
|
42
43
|
|
|
43
|
-
const numberBool: {
|
|
44
|
+
const numberBool: {[n: number]: boolean} = {1: true};
|
|
44
45
|
|
|
45
46
|
type NumberBool = typeof numberBool[number];
|
|
46
47
|
//=> boolean
|
|
@@ -12,18 +12,19 @@ Use-cases:
|
|
|
12
12
|
```
|
|
13
13
|
import type {UndefinedOnPartialDeep} from 'type-fest';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
type Settings = {
|
|
16
16
|
optionA: string;
|
|
17
17
|
optionB?: number;
|
|
18
18
|
subOption: {
|
|
19
19
|
subOptionA: boolean;
|
|
20
20
|
subOptionB?: boolean;
|
|
21
|
-
}
|
|
21
|
+
};
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const testSettingsA: Settings = {
|
|
25
25
|
optionA: 'foo',
|
|
26
26
|
optionB: undefined, // TypeScript error if `exactOptionalPropertyTypes` is true.
|
|
27
|
+
// @ts-expect-error
|
|
27
28
|
subOption: {
|
|
28
29
|
subOptionA: true,
|
|
29
30
|
subOptionB: undefined, // TypeScript error if `exactOptionalPropertyTypes` is true
|
|
@@ -32,10 +33,10 @@ const testSettingsA: Settings = {
|
|
|
32
33
|
|
|
33
34
|
const testSettingsB: UndefinedOnPartialDeep<Settings> = {
|
|
34
35
|
optionA: 'foo',
|
|
35
|
-
optionB: undefined, //
|
|
36
|
+
optionB: undefined, // `optionB` can be set to `undefined` now.
|
|
36
37
|
subOption: {
|
|
37
38
|
subOptionA: true,
|
|
38
|
-
subOptionB: undefined, //
|
|
39
|
+
subOptionB: undefined, // `subOptionB` can be set to `undefined` now.
|
|
39
40
|
},
|
|
40
41
|
};
|
|
41
42
|
```
|
|
@@ -13,34 +13,6 @@ type Intersection = UnionToIntersection<Union>;
|
|
|
13
13
|
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
A more applicable example which could make its way into your library code follows.
|
|
17
|
-
|
|
18
|
-
@example
|
|
19
|
-
```
|
|
20
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
21
|
-
|
|
22
|
-
class CommandOne {
|
|
23
|
-
commands: {
|
|
24
|
-
a1: () => undefined,
|
|
25
|
-
b1: () => undefined,
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
class CommandTwo {
|
|
30
|
-
commands: {
|
|
31
|
-
a2: (argA: string) => undefined,
|
|
32
|
-
b2: (argB: string) => undefined,
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
37
|
-
type Union = typeof union;
|
|
38
|
-
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
39
|
-
|
|
40
|
-
type Intersection = UnionToIntersection<Union>;
|
|
41
|
-
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
16
|
@category Type
|
|
45
17
|
*/
|
|
46
18
|
export type UnionToIntersection<Union> = (
|
package/source/value-of.d.ts
CHANGED
|
@@ -5,36 +5,16 @@ Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31438)
|
|
|
5
5
|
|
|
6
6
|
@example
|
|
7
7
|
```
|
|
8
|
-
// data.json
|
|
9
|
-
{
|
|
10
|
-
'foo': 1,
|
|
11
|
-
'bar': 2,
|
|
12
|
-
'biz': 3
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// main.ts
|
|
16
8
|
import type {ValueOf} from 'type-fest';
|
|
17
|
-
import data = require('./data.json');
|
|
18
|
-
|
|
19
|
-
export function getData(name: string): ValueOf<typeof data> {
|
|
20
|
-
return data[name];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function onlyBar(name: string): ValueOf<typeof data, 'bar'> {
|
|
24
|
-
return data[name];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// file.ts
|
|
28
|
-
import {getData, onlyBar} from './main.d.ts';
|
|
29
9
|
|
|
30
|
-
|
|
31
|
-
//=>
|
|
10
|
+
type A = ValueOf<{id: number; name: string; active: boolean}>;
|
|
11
|
+
//=> number | string | boolean
|
|
32
12
|
|
|
33
|
-
|
|
34
|
-
//=>
|
|
13
|
+
type B = ValueOf<{id: number; name: string; active: boolean}, 'name'>;
|
|
14
|
+
//=> string
|
|
35
15
|
|
|
36
|
-
|
|
37
|
-
//=>
|
|
16
|
+
type C = ValueOf<{id: number; name: string; active: boolean}, 'id' | 'name'>;
|
|
17
|
+
//=> number | string
|
|
38
18
|
```
|
|
39
19
|
|
|
40
20
|
@category Object
|
package/source/words.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ writableDeepFoo.b = ['something'];
|
|
|
23
23
|
|
|
24
24
|
Note that types containing overloaded functions are not made deeply writable due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
|
|
25
25
|
|
|
26
|
-
@see Writable
|
|
26
|
+
@see {@link Writable}
|
|
27
27
|
@category Object
|
|
28
28
|
@category Array
|
|
29
29
|
@category Set
|
|
@@ -9,12 +9,12 @@ This is useful when you want to create a new type that contains writable keys on
|
|
|
9
9
|
```
|
|
10
10
|
import type {WritableKeysOf} from 'type-fest';
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
type User = {
|
|
13
13
|
name: string;
|
|
14
14
|
surname: string;
|
|
15
15
|
|
|
16
16
|
readonly id: number;
|
|
17
|
-
}
|
|
17
|
+
};
|
|
18
18
|
|
|
19
19
|
type UpdateRequest<Entity extends object> = Pick<Entity, WritableKeysOf<Entity>>;
|
|
20
20
|
|
package/source/writable.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ type Foo = {
|
|
|
32
32
|
|
|
33
33
|
const writableFoo: Writable<Foo> = {a: 1, b: ['2'], c: true};
|
|
34
34
|
writableFoo.a = 3;
|
|
35
|
+
// @ts-expect-error
|
|
35
36
|
writableFoo.b[0] = 'new value'; // Will still fail as the value of property "b" is still a readonly type.
|
|
36
37
|
writableFoo.b = ['something']; // Will work as the "b" property itself is no longer readonly.
|
|
37
38
|
|
|
@@ -44,6 +45,7 @@ type SomeWritable = Writable<Foo, 'b' | 'c'>;
|
|
|
44
45
|
|
|
45
46
|
// Also supports array
|
|
46
47
|
const readonlyArray: readonly number[] = [1, 2, 3];
|
|
48
|
+
// @ts-expect-error
|
|
47
49
|
readonlyArray.push(4); // Will fail as the array itself is readonly.
|
|
48
50
|
const writableArray: Writable<typeof readonlyArray> = readonlyArray as Writable<typeof readonlyArray>;
|
|
49
51
|
writableArray.push(4); // Will work as the array itself is now writable.
|