type-fest 2.18.1 → 3.0.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 +81 -72
- package/package.json +11 -10
- package/readme.md +26 -16
- package/source/async-return-type.d.ts +1 -3
- package/source/asyncify.d.ts +1 -2
- package/source/basic.d.ts +1 -1
- package/source/camel-case.d.ts +2 -2
- package/source/camel-cased-properties-deep.d.ts +5 -5
- package/source/camel-cased-properties.d.ts +3 -3
- package/source/conditional-except.d.ts +2 -2
- package/source/conditional-keys.d.ts +11 -11
- package/source/conditional-pick-deep.d.ts +102 -0
- package/source/conditional-pick.d.ts +2 -2
- package/source/conditional-simplify.d.ts +32 -0
- package/source/delimiter-case.d.ts +30 -24
- package/source/delimiter-cased-properties-deep.d.ts +6 -6
- package/source/delimiter-cased-properties.d.ts +2 -2
- package/source/empty-object.d.ts +46 -0
- package/source/enforce-optional.d.ts +47 -0
- package/source/entries.d.ts +3 -3
- package/source/entry.d.ts +3 -3
- package/source/exact.d.ts +31 -9
- package/source/fixed-length-array.d.ts +2 -2
- package/source/get.d.ts +52 -45
- package/source/has-optional-keys.d.ts +1 -1
- package/source/has-required-keys.d.ts +1 -1
- package/source/iterable-element.d.ts +4 -4
- package/source/join.d.ts +2 -2
- package/source/jsonify.d.ts +42 -20
- package/source/last-array-element.d.ts +4 -4
- package/source/literal-to-primitive.d.ts +12 -12
- package/source/merge.d.ts +33 -10
- package/source/observable-like.d.ts +3 -2
- package/source/{remove-index-signature.d.ts → omit-index-signature.d.ts} +14 -11
- package/source/package-json.d.ts +55 -29
- package/source/partial-deep.d.ts +29 -31
- package/source/partial-on-undefined-deep.d.ts +12 -12
- package/source/pascal-cased-properties-deep.d.ts +5 -5
- package/source/pascal-cased-properties.d.ts +2 -2
- package/source/pick-index-signature.d.ts +102 -0
- package/source/readonly-deep.d.ts +14 -16
- package/source/require-all-or-none.d.ts +1 -1
- package/source/require-at-least-one.d.ts +4 -4
- package/source/schema.d.ts +22 -22
- package/source/set-non-nullable.d.ts +35 -0
- package/source/set-optional.d.ts +4 -4
- package/source/set-required.d.ts +4 -4
- package/source/simplify.d.ts +1 -26
- package/source/split.d.ts +2 -2
- package/source/spread.d.ts +4 -4
- package/source/tsconfig-json.d.ts +16 -12
- package/source/tuple-to-union.d.ts +51 -0
- package/source/union-to-intersection.d.ts +3 -3
- package/source/writable.d.ts +4 -4
- package/source/mutable.d.ts +0 -5
- package/source/promise-value.d.ts +0 -29
package/source/merge.d.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type {OmitIndexSignature} from './omit-index-signature';
|
|
2
|
+
import type {PickIndexSignature} from './pick-index-signature';
|
|
3
|
+
import type {EnforceOptional} from './enforce-optional';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
// Merges two objects without worrying about index signatures or optional keys.
|
|
6
|
+
type SimpleMerge<Destination, Source> = {
|
|
7
|
+
[Key in keyof Destination | keyof Source]: Key extends keyof Source
|
|
8
|
+
? Source[Key]
|
|
9
|
+
: Key extends keyof Destination
|
|
10
|
+
? Destination[Key]
|
|
11
|
+
: never;
|
|
12
|
+
};
|
|
5
13
|
|
|
6
14
|
/**
|
|
7
15
|
Merge two types into a new type. Keys of the second type overrides keys of the first type.
|
|
@@ -10,18 +18,33 @@ Merge two types into a new type. Keys of the second type overrides keys of the f
|
|
|
10
18
|
```
|
|
11
19
|
import type {Merge} from 'type-fest';
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
interface Foo {
|
|
22
|
+
[x: string]: unknown;
|
|
23
|
+
[x: number]: unknown;
|
|
24
|
+
foo: string;
|
|
25
|
+
bar: symbol;
|
|
26
|
+
}
|
|
17
27
|
|
|
18
28
|
type Bar = {
|
|
19
|
-
|
|
29
|
+
[x: number]: number;
|
|
30
|
+
[x: symbol]: unknown;
|
|
31
|
+
bar: Date;
|
|
32
|
+
baz: boolean;
|
|
20
33
|
};
|
|
21
34
|
|
|
22
|
-
|
|
35
|
+
export type FooBar = Merge<Foo, Bar>;
|
|
36
|
+
// => {
|
|
37
|
+
// [x: string]: unknown;
|
|
38
|
+
// [x: number]: number;
|
|
39
|
+
// [x: symbol]: unknown;
|
|
40
|
+
// foo: string;
|
|
41
|
+
// bar: Date;
|
|
42
|
+
// baz: boolean;
|
|
43
|
+
// }
|
|
23
44
|
```
|
|
24
45
|
|
|
25
46
|
@category Object
|
|
26
47
|
*/
|
|
27
|
-
export type Merge<
|
|
48
|
+
export type Merge<Destination, Source> = EnforceOptional<
|
|
49
|
+
SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>>
|
|
50
|
+
& SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
declare global {
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
|
|
2
3
|
interface SymbolConstructor {
|
|
3
4
|
readonly observable: symbol;
|
|
4
5
|
}
|
|
@@ -56,7 +57,7 @@ But `Observable` implementations have evolved to preferring case 2 and some impl
|
|
|
56
57
|
|
|
57
58
|
@category Observable
|
|
58
59
|
*/
|
|
59
|
-
export
|
|
60
|
+
export type ObservableLike<ValueType = unknown> = {
|
|
60
61
|
subscribe(observer?: Partial<Observer<ValueType>>): Unsubscribable;
|
|
61
62
|
[Symbol.observable](): ObservableLike<ValueType>;
|
|
62
|
-
}
|
|
63
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
2
|
+
Omit any index signatures from the given object type, leaving only explicitly defined properties.
|
|
3
|
+
|
|
4
|
+
This is the counterpart of `PickIndexSignature`.
|
|
3
5
|
|
|
4
6
|
Use-cases:
|
|
5
7
|
- Remove overly permissive signatures from third-party types.
|
|
@@ -34,20 +36,20 @@ type Keyed = {} extends Record<'foo' | 'bar', unknown>
|
|
|
34
36
|
Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`...
|
|
35
37
|
|
|
36
38
|
```
|
|
37
|
-
import type {
|
|
39
|
+
import type {OmitIndexSignature} from 'type-fest';
|
|
38
40
|
|
|
39
|
-
type
|
|
41
|
+
type OmitIndexSignature<ObjectType> = {
|
|
40
42
|
[KeyType in keyof ObjectType // Map each key of `ObjectType`...
|
|
41
|
-
]: ObjectType[KeyType]; // ...to its original value, i.e. `
|
|
43
|
+
]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.
|
|
42
44
|
};
|
|
43
45
|
```
|
|
44
46
|
|
|
45
47
|
...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)...
|
|
46
48
|
|
|
47
49
|
```
|
|
48
|
-
import type {
|
|
50
|
+
import type {OmitIndexSignature} from 'type-fest';
|
|
49
51
|
|
|
50
|
-
type
|
|
52
|
+
type OmitIndexSignature<ObjectType> = {
|
|
51
53
|
[KeyType in keyof ObjectType
|
|
52
54
|
// Is `{}` assignable to `Record<KeyType, unknown>`?
|
|
53
55
|
as {} extends Record<KeyType, unknown>
|
|
@@ -60,9 +62,9 @@ type RemoveIndexSignature<ObjectType> = {
|
|
|
60
62
|
If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it.
|
|
61
63
|
|
|
62
64
|
```
|
|
63
|
-
import type {
|
|
65
|
+
import type {OmitIndexSignature} from 'type-fest';
|
|
64
66
|
|
|
65
|
-
type
|
|
67
|
+
type OmitIndexSignature<ObjectType> = {
|
|
66
68
|
[KeyType in keyof ObjectType
|
|
67
69
|
as {} extends Record<KeyType, unknown>
|
|
68
70
|
? never // => Remove this `KeyType`.
|
|
@@ -73,7 +75,7 @@ type RemoveIndexSignature<ObjectType> = {
|
|
|
73
75
|
|
|
74
76
|
@example
|
|
75
77
|
```
|
|
76
|
-
import type {
|
|
78
|
+
import type {OmitIndexSignature} from 'type-fest';
|
|
77
79
|
|
|
78
80
|
interface Example {
|
|
79
81
|
// These index signatures will be removed.
|
|
@@ -91,13 +93,14 @@ interface Example {
|
|
|
91
93
|
qux?: 'baz';
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
type ExampleWithoutIndexSignatures =
|
|
96
|
+
type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
|
|
95
97
|
// => { foo: 'bar'; qux?: 'baz' | undefined; }
|
|
96
98
|
```
|
|
97
99
|
|
|
100
|
+
@see PickIndexSignature
|
|
98
101
|
@category Object
|
|
99
102
|
*/
|
|
100
|
-
export type
|
|
103
|
+
export type OmitIndexSignature<ObjectType> = {
|
|
101
104
|
[KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
|
|
102
105
|
? never
|
|
103
106
|
: KeyType]: ObjectType[KeyType];
|
package/source/package-json.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {LiteralUnion} from './literal-union';
|
|
2
|
+
import type {JsonObject, JsonValue} from './basic';
|
|
2
3
|
|
|
3
4
|
declare namespace PackageJson {
|
|
4
5
|
/**
|
|
@@ -26,8 +27,8 @@ declare namespace PackageJson {
|
|
|
26
27
|
email?: string;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
export
|
|
30
|
-
[directoryType: string]:
|
|
30
|
+
export type DirectoryLocations = {
|
|
31
|
+
[directoryType: string]: JsonValue | undefined;
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
Location for executable scripts. Sugar to generate entries in the `bin` property by walking the folder.
|
|
@@ -58,7 +59,7 @@ declare namespace PackageJson {
|
|
|
58
59
|
Location for test files.
|
|
59
60
|
*/
|
|
60
61
|
test?: string;
|
|
61
|
-
}
|
|
62
|
+
};
|
|
62
63
|
|
|
63
64
|
export type Scripts = {
|
|
64
65
|
/**
|
|
@@ -211,27 +212,29 @@ declare namespace PackageJson {
|
|
|
211
212
|
Conditions which provide a way to resolve a package entry point based on the environment.
|
|
212
213
|
*/
|
|
213
214
|
export type ExportCondition = LiteralUnion<
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
215
|
+
| 'import'
|
|
216
|
+
| 'require'
|
|
217
|
+
| 'node'
|
|
218
|
+
| 'node-addons'
|
|
219
|
+
| 'deno'
|
|
220
|
+
| 'browser'
|
|
221
|
+
| 'electron'
|
|
222
|
+
| 'react-native'
|
|
223
|
+
| 'default',
|
|
224
|
+
string
|
|
224
225
|
>;
|
|
225
226
|
|
|
227
|
+
type ExportConditions = {[condition in ExportCondition]: Exports};
|
|
228
|
+
|
|
226
229
|
/**
|
|
227
230
|
Entry points of a module, optionally with conditions and subpath exports.
|
|
228
231
|
*/
|
|
229
232
|
export type Exports =
|
|
230
233
|
| null
|
|
231
234
|
| string
|
|
232
|
-
| string
|
|
233
|
-
|
|
|
234
|
-
| {[
|
|
235
|
+
| Array<string | ExportConditions>
|
|
236
|
+
| ExportConditions
|
|
237
|
+
| {[path: string]: Exports};
|
|
235
238
|
|
|
236
239
|
/**
|
|
237
240
|
Import map entries of a module, optionally with conditions.
|
|
@@ -240,6 +243,7 @@ declare namespace PackageJson {
|
|
|
240
243
|
[key: string]: string | {[key in ExportCondition]: Exports};
|
|
241
244
|
};
|
|
242
245
|
|
|
246
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
243
247
|
export interface NonStandardEntryPoints {
|
|
244
248
|
/**
|
|
245
249
|
An ECMAScript module ID that is the primary entry point to the program.
|
|
@@ -272,7 +276,7 @@ declare namespace PackageJson {
|
|
|
272
276
|
sideEffects?: boolean | string[];
|
|
273
277
|
}
|
|
274
278
|
|
|
275
|
-
export
|
|
279
|
+
export type TypeScriptConfiguration = {
|
|
276
280
|
/**
|
|
277
281
|
Location of the bundled TypeScript declaration file.
|
|
278
282
|
*/
|
|
@@ -287,12 +291,12 @@ declare namespace PackageJson {
|
|
|
287
291
|
Location of the bundled TypeScript declaration file. Alias of `types`.
|
|
288
292
|
*/
|
|
289
293
|
typings?: string;
|
|
290
|
-
}
|
|
294
|
+
};
|
|
291
295
|
|
|
292
296
|
/**
|
|
293
297
|
An alternative configuration for Yarn workspaces.
|
|
294
298
|
*/
|
|
295
|
-
export
|
|
299
|
+
export type WorkspaceConfig = {
|
|
296
300
|
/**
|
|
297
301
|
An array of workspace pattern strings which contain the workspace packages.
|
|
298
302
|
*/
|
|
@@ -304,7 +308,7 @@ declare namespace PackageJson {
|
|
|
304
308
|
[Read more](https://classic.yarnpkg.com/blog/2018/02/15/nohoist/)
|
|
305
309
|
*/
|
|
306
310
|
nohoist?: WorkspacePattern[];
|
|
307
|
-
}
|
|
311
|
+
};
|
|
308
312
|
|
|
309
313
|
/**
|
|
310
314
|
A workspace pattern points to a directory or group of directories which contain packages that should be included in the workspace installation process.
|
|
@@ -317,7 +321,7 @@ declare namespace PackageJson {
|
|
|
317
321
|
*/
|
|
318
322
|
type WorkspacePattern = string;
|
|
319
323
|
|
|
320
|
-
export
|
|
324
|
+
export type YarnConfiguration = {
|
|
321
325
|
/**
|
|
322
326
|
Used to configure [Yarn workspaces](https://classic.yarnpkg.com/docs/workspaces/).
|
|
323
327
|
|
|
@@ -338,18 +342,19 @@ declare namespace PackageJson {
|
|
|
338
342
|
Selective version resolutions. Allows the definition of custom package versions inside dependencies without manual edits in the `yarn.lock` file.
|
|
339
343
|
*/
|
|
340
344
|
resolutions?: Dependency;
|
|
341
|
-
}
|
|
345
|
+
};
|
|
342
346
|
|
|
343
|
-
export
|
|
347
|
+
export type JSPMConfiguration = {
|
|
344
348
|
/**
|
|
345
349
|
JSPM configuration.
|
|
346
350
|
*/
|
|
347
351
|
jspm?: PackageJson;
|
|
348
|
-
}
|
|
352
|
+
};
|
|
349
353
|
|
|
350
354
|
/**
|
|
351
355
|
Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Containing standard npm properties.
|
|
352
356
|
*/
|
|
357
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
353
358
|
export interface PackageJsonStandard {
|
|
354
359
|
/**
|
|
355
360
|
The name of the package.
|
|
@@ -479,7 +484,7 @@ declare namespace PackageJson {
|
|
|
479
484
|
/**
|
|
480
485
|
Is used to set configuration parameters used in package scripts that persist across upgrades.
|
|
481
486
|
*/
|
|
482
|
-
config?:
|
|
487
|
+
config?: JsonObject;
|
|
483
488
|
|
|
484
489
|
/**
|
|
485
490
|
The dependencies of the package.
|
|
@@ -520,7 +525,7 @@ declare namespace PackageJson {
|
|
|
520
525
|
Engines that this package runs on.
|
|
521
526
|
*/
|
|
522
527
|
engines?: {
|
|
523
|
-
[EngineName in 'npm' | 'node' | string]?: string;
|
|
528
|
+
[EngineName in 'npm' | 'node' | string]?: string; // eslint-disable-line @typescript-eslint/no-redundant-type-constituents
|
|
524
529
|
};
|
|
525
530
|
|
|
526
531
|
/**
|
|
@@ -621,11 +626,30 @@ declare namespace PackageJson {
|
|
|
621
626
|
};
|
|
622
627
|
}
|
|
623
628
|
|
|
624
|
-
|
|
629
|
+
/**
|
|
630
|
+
Type for [`package.json` file used by the Node.js runtime](https://nodejs.org/api/packages.html#nodejs-packagejson-field-definitions).
|
|
631
|
+
*/
|
|
632
|
+
export type NodeJsStandard = {
|
|
633
|
+
/**
|
|
634
|
+
Defines which package manager is expected to be used when working on the current project. It can set to any of the [supported package managers](https://nodejs.org/api/corepack.html#supported-package-managers), and will ensure that your teams use the exact same package manager versions without having to install anything else than Node.js.
|
|
635
|
+
|
|
636
|
+
__This field is currently experimental and needs to be opted-in; check the [Corepack](https://nodejs.org/api/corepack.html) page for details about the procedure.__
|
|
637
|
+
|
|
638
|
+
@example
|
|
639
|
+
```json
|
|
640
|
+
{
|
|
641
|
+
"packageManager": "<package manager name>@<version>"
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
*/
|
|
645
|
+
packageManager?: string;
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
export type PublishConfig = {
|
|
625
649
|
/**
|
|
626
650
|
Additional, less common properties from the [npm docs on `publishConfig`](https://docs.npmjs.com/cli/v7/configuring-npm/package-json#publishconfig).
|
|
627
651
|
*/
|
|
628
|
-
[additionalProperties: string]:
|
|
652
|
+
[additionalProperties: string]: JsonValue | undefined;
|
|
629
653
|
|
|
630
654
|
/**
|
|
631
655
|
When publishing scoped packages, the access level defaults to restricted. If you want your scoped package to be publicly viewable (and installable) set `--access=public`. The only valid values for access are public and restricted. Unscoped packages always have an access level of public.
|
|
@@ -645,7 +669,7 @@ declare namespace PackageJson {
|
|
|
645
669
|
Default: `'latest'`
|
|
646
670
|
*/
|
|
647
671
|
tag?: string;
|
|
648
|
-
}
|
|
672
|
+
};
|
|
649
673
|
}
|
|
650
674
|
|
|
651
675
|
/**
|
|
@@ -654,6 +678,8 @@ Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-j
|
|
|
654
678
|
@category File
|
|
655
679
|
*/
|
|
656
680
|
export type PackageJson =
|
|
681
|
+
JsonObject &
|
|
682
|
+
PackageJson.NodeJsStandard &
|
|
657
683
|
PackageJson.PackageJsonStandard &
|
|
658
684
|
PackageJson.NonStandardEntryPoints &
|
|
659
685
|
PackageJson.TypeScriptConfiguration &
|
package/source/partial-deep.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ import type {BuiltIns} from './internal';
|
|
|
3
3
|
/**
|
|
4
4
|
@see PartialDeep
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
6
|
+
export type PartialDeepOptions = {
|
|
7
7
|
/**
|
|
8
8
|
Whether to affect the individual elements of arrays and tuples.
|
|
9
9
|
|
|
10
|
-
@default
|
|
10
|
+
@default false
|
|
11
11
|
*/
|
|
12
12
|
readonly recurseIntoArrays?: boolean;
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
Create a type from another type with all keys and nested keys set to optional.
|
|
@@ -40,7 +40,7 @@ const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {
|
|
|
40
40
|
settings = applySavedSettings({textEditor: {fontWeight: 500}});
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
By default, this
|
|
43
|
+
By default, this does not affect elements in array and tuple types. You can change this by passing `{recurseIntoArrays: true}` as the second type argument:
|
|
44
44
|
|
|
45
45
|
```
|
|
46
46
|
import type {PartialDeep} from 'type-fest';
|
|
@@ -49,13 +49,11 @@ interface Settings {
|
|
|
49
49
|
languages: string[];
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const partialSettings: PartialDeep<Settings> = {
|
|
52
|
+
const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true}> = {
|
|
53
53
|
languages: [undefined]
|
|
54
54
|
};
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
If this is undesirable, you can pass `{recurseIntoArrays: false}` as the second type argument.
|
|
58
|
-
|
|
59
57
|
@category Object
|
|
60
58
|
@category Array
|
|
61
59
|
@category Set
|
|
@@ -64,46 +62,46 @@ If this is undesirable, you can pass `{recurseIntoArrays: false}` as the second
|
|
|
64
62
|
export type PartialDeep<T, Options extends PartialDeepOptions = {}> = T extends BuiltIns
|
|
65
63
|
? T
|
|
66
64
|
: T extends Map<infer KeyType, infer ValueType>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
65
|
+
? PartialMapDeep<KeyType, ValueType, Options>
|
|
66
|
+
: T extends Set<infer ItemType>
|
|
67
|
+
? PartialSetDeep<ItemType, Options>
|
|
68
|
+
: T extends ReadonlyMap<infer KeyType, infer ValueType>
|
|
69
|
+
? PartialReadonlyMapDeep<KeyType, ValueType, Options>
|
|
70
|
+
: T extends ReadonlySet<infer ItemType>
|
|
71
|
+
? PartialReadonlySetDeep<ItemType, Options>
|
|
72
|
+
: T extends ((...arguments: any[]) => unknown)
|
|
73
|
+
? T | undefined
|
|
74
|
+
: T extends object
|
|
75
|
+
? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
|
|
76
|
+
? Options['recurseIntoArrays'] extends true
|
|
77
|
+
? ItemType[] extends T // Test for arrays (non-tuples) specifically
|
|
78
|
+
? readonly ItemType[] extends T // Differentiate readonly and mutable arrays
|
|
79
|
+
? ReadonlyArray<PartialDeep<ItemType | undefined, Options>>
|
|
80
|
+
: Array<PartialDeep<ItemType | undefined, Options>>
|
|
81
|
+
: PartialObjectDeep<T, Options> // Tuples behave properly
|
|
82
|
+
: T // If they don't opt into array testing, just use the original type
|
|
83
|
+
: PartialObjectDeep<T, Options>
|
|
84
|
+
: unknown;
|
|
87
85
|
|
|
88
86
|
/**
|
|
89
87
|
Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
|
|
90
88
|
*/
|
|
91
|
-
|
|
89
|
+
type PartialMapDeep<KeyType, ValueType, Options extends PartialDeepOptions> = {} & Map<PartialDeep<KeyType, Options>, PartialDeep<ValueType, Options>>;
|
|
92
90
|
|
|
93
91
|
/**
|
|
94
92
|
Same as `PartialDeep`, but accepts only `Set`s as inputs. Internal helper for `PartialDeep`.
|
|
95
93
|
*/
|
|
96
|
-
|
|
94
|
+
type PartialSetDeep<T, Options extends PartialDeepOptions> = {} & Set<PartialDeep<T, Options>>;
|
|
97
95
|
|
|
98
96
|
/**
|
|
99
97
|
Same as `PartialDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `PartialDeep`.
|
|
100
98
|
*/
|
|
101
|
-
|
|
99
|
+
type PartialReadonlyMapDeep<KeyType, ValueType, Options extends PartialDeepOptions> = {} & ReadonlyMap<PartialDeep<KeyType, Options>, PartialDeep<ValueType, Options>>;
|
|
102
100
|
|
|
103
101
|
/**
|
|
104
102
|
Same as `PartialDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `PartialDeep`.
|
|
105
103
|
*/
|
|
106
|
-
|
|
104
|
+
type PartialReadonlySetDeep<T, Options extends PartialDeepOptions> = {} & ReadonlySet<PartialDeep<T, Options>>;
|
|
107
105
|
|
|
108
106
|
/**
|
|
109
107
|
Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
|
|
@@ -4,14 +4,14 @@ import type {Merge} from './merge';
|
|
|
4
4
|
/**
|
|
5
5
|
@see PartialOnUndefinedDeep
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
7
|
+
export type PartialOnUndefinedDeepOptions = {
|
|
8
8
|
/**
|
|
9
9
|
Whether to affect the individual elements of arrays and tuples.
|
|
10
10
|
|
|
11
11
|
@default false
|
|
12
12
|
*/
|
|
13
13
|
readonly recurseIntoArrays?: boolean;
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
Create a deep version of another type where all keys accepting `undefined` type are set to optional.
|
|
@@ -58,13 +58,13 @@ Utility type to get the value type by key and recursively call `PartialOnUndefin
|
|
|
58
58
|
type PartialOnUndefinedDeepValue<T, Options extends PartialOnUndefinedDeepOptions> = T extends BuiltIns | ((...arguments: any[]) => unknown)
|
|
59
59
|
? T
|
|
60
60
|
: T extends ReadonlyArray<infer U> // Test if type is array or tuple
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
? Options['recurseIntoArrays'] extends true // Check if option is activated
|
|
62
|
+
? U[] extends T // Check if array not tuple
|
|
63
|
+
? readonly U[] extends T
|
|
64
|
+
? ReadonlyArray<PartialOnUndefinedDeep<U, Options>> // Readonly array treatment
|
|
65
|
+
: Array<PartialOnUndefinedDeep<U, Options>> // Mutable array treatment
|
|
66
|
+
: PartialOnUndefinedDeep<{[Key in keyof T]: PartialOnUndefinedDeep<T[Key], Options>}, Options> // Tuple treatment
|
|
67
|
+
: T
|
|
68
|
+
: T extends Record<any, any> | undefined
|
|
69
|
+
? PartialOnUndefinedDeep<T, Options>
|
|
70
|
+
: unknown;
|
|
@@ -47,8 +47,8 @@ const result: PascalCasedPropertiesDeep<UserWithFriends> = {
|
|
|
47
47
|
export type PascalCasedPropertiesDeep<Value> = Value extends Function | Date | RegExp
|
|
48
48
|
? Value
|
|
49
49
|
: Value extends Array<infer U>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
? Array<PascalCasedPropertiesDeep<U>>
|
|
51
|
+
: Value extends Set<infer U>
|
|
52
|
+
? Set<PascalCasedPropertiesDeep<U>> : {
|
|
53
|
+
[K in keyof Value as PascalCase<K>]: PascalCasedPropertiesDeep<Value[K]>;
|
|
54
|
+
};
|
|
@@ -30,5 +30,5 @@ const result: PascalCasedProperties<User> = {
|
|
|
30
30
|
export type PascalCasedProperties<Value> = Value extends Function
|
|
31
31
|
? Value
|
|
32
32
|
: Value extends Array<infer U>
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
? Value
|
|
34
|
+
: {[K in keyof Value as PascalCase<K>]: Value[K]};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Pick only index signatures from the given object type, leaving out all explicitly defined properties.
|
|
3
|
+
|
|
4
|
+
This is the counterpart of `OmitIndexSignature`.
|
|
5
|
+
|
|
6
|
+
When you use a type that will iterate through an object that has indexed keys and explicitly defined keys you end up with a type where only the indexed keys are kept. This is because `keyof` of an indexed type always returns `string | number | symbol`, because every key is possible in that object. With this type, you can save the indexed keys and reinject them later, like in the second example below.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {PickIndexSignature} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
declare const symbolKey: unique symbol;
|
|
13
|
+
|
|
14
|
+
type Example = {
|
|
15
|
+
// These index signatures will remain.
|
|
16
|
+
[x: string]: unknown;
|
|
17
|
+
[x: number]: unknown;
|
|
18
|
+
[x: symbol]: unknown;
|
|
19
|
+
[x: `head-${string}`]: string;
|
|
20
|
+
[x: `${string}-tail`]: string;
|
|
21
|
+
[x: `head-${string}-tail`]: string;
|
|
22
|
+
[x: `${bigint}`]: string;
|
|
23
|
+
[x: `embedded-${number}`]: string;
|
|
24
|
+
|
|
25
|
+
// These explicitly defined keys will be removed.
|
|
26
|
+
['snake-case-key']: string;
|
|
27
|
+
[symbolKey]: string;
|
|
28
|
+
foo: 'bar';
|
|
29
|
+
qux?: 'baz';
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type ExampleIndexSignature = PickIndexSignature<Example>;
|
|
33
|
+
// {
|
|
34
|
+
// [x: string]: unknown;
|
|
35
|
+
// [x: number]: unknown;
|
|
36
|
+
// [x: symbol]: unknown;
|
|
37
|
+
// [x: `head-${string}`]: string;
|
|
38
|
+
// [x: `${string}-tail`]: string;
|
|
39
|
+
// [x: `head-${string}-tail`]: string;
|
|
40
|
+
// [x: `${bigint}`]: string;
|
|
41
|
+
// [x: `embedded-${number}`]: string;
|
|
42
|
+
// }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
@example
|
|
46
|
+
```
|
|
47
|
+
import type {OmitIndexSignature, PickIndexSignature, Simplify} from 'type-fest';
|
|
48
|
+
|
|
49
|
+
type Foo = {
|
|
50
|
+
[x: string]: string;
|
|
51
|
+
foo: string;
|
|
52
|
+
bar: number;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Imagine that you want a new type `Bar` that comes from `Foo`.
|
|
56
|
+
// => {
|
|
57
|
+
// [x: string]: string;
|
|
58
|
+
// bar: number;
|
|
59
|
+
// };
|
|
60
|
+
|
|
61
|
+
type Bar = Omit<Foo, 'foo'>;
|
|
62
|
+
// This is not working because `Omit` returns only indexed keys.
|
|
63
|
+
// => {
|
|
64
|
+
// [x: string]: string;
|
|
65
|
+
// [x: number]: string;
|
|
66
|
+
// }
|
|
67
|
+
|
|
68
|
+
// One solution is to save the indexed signatures to new type.
|
|
69
|
+
type FooIndexSignature = PickIndexSignature<Foo>;
|
|
70
|
+
// => {
|
|
71
|
+
// [x: string]: string;
|
|
72
|
+
// }
|
|
73
|
+
|
|
74
|
+
// Get a new type without index signatures.
|
|
75
|
+
type FooWithoutIndexSignature = OmitIndexSignature<Foo>;
|
|
76
|
+
// => {
|
|
77
|
+
// foo: string;
|
|
78
|
+
// bar: number;
|
|
79
|
+
// }
|
|
80
|
+
|
|
81
|
+
// At this point we can use Omit to get our new type.
|
|
82
|
+
type BarWithoutIndexSignature = Omit<FooWithoutIndexSignature, 'foo'>;
|
|
83
|
+
// => {
|
|
84
|
+
// bar: number;
|
|
85
|
+
// }
|
|
86
|
+
|
|
87
|
+
// And finally we can merge back the indexed signatures.
|
|
88
|
+
type BarWithIndexSignature = Simplify<BarWithoutIndexSignature & FooIndexSignature>;
|
|
89
|
+
// => {
|
|
90
|
+
// [x: string]: string;
|
|
91
|
+
// bar: number;
|
|
92
|
+
// }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
@see OmitIndexSignature
|
|
96
|
+
@category Object
|
|
97
|
+
*/
|
|
98
|
+
export type PickIndexSignature<ObjectType> = {
|
|
99
|
+
[KeyType in keyof ObjectType as {} extends Record<KeyType, unknown>
|
|
100
|
+
? KeyType
|
|
101
|
+
: never]: ObjectType[KeyType];
|
|
102
|
+
};
|