type-fest 2.17.0 → 2.18.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 CHANGED
@@ -15,6 +15,7 @@ export {RequireExactlyOne} from './source/require-exactly-one';
15
15
  export {RequireAllOrNone} from './source/require-all-or-none';
16
16
  export {RemoveIndexSignature} from './source/remove-index-signature';
17
17
  export {PartialDeep, PartialDeepOptions} from './source/partial-deep';
18
+ export {PartialOnUndefinedDeep, PartialOnUndefinedDeepOptions} from './source/partial-on-undefined-deep';
18
19
  export {ReadonlyDeep} from './source/readonly-deep';
19
20
  export {LiteralUnion} from './source/literal-union';
20
21
  export {Promisable} from './source/promisable';
@@ -61,6 +62,7 @@ export {OptionalKeysOf} from './source/optional-keys-of';
61
62
  export {HasOptionalKeys} from './source/has-optional-keys';
62
63
  export {RequiredKeysOf} from './source/required-keys-of';
63
64
  export {HasRequiredKeys} from './source/has-required-keys';
65
+ export {Spread} from './source/spread';
64
66
 
65
67
  // Template literal types
66
68
  export {CamelCase} from './source/camel-case';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "2.17.0",
3
+ "version": "2.18.0",
4
4
  "description": "A collection of essential TypeScript types",
5
5
  "license": "(MIT OR CC0-1.0)",
6
6
  "repository": "sindresorhus/type-fest",
package/readme.md CHANGED
@@ -40,41 +40,6 @@
40
40
  <br>
41
41
  <br>
42
42
  <br>
43
- <a href="https://neverinstall.com/spaces/devtools?utm_source=github&utm_medium=sponsor&utm_campaign=sindre#gh-light-mode-only">
44
- <div>
45
- <img src="https://sindresorhus.com/assets/thanks/neverinstall-logo-light.svg" width="200" alt="neverinstall">
46
- </div>
47
- <br>
48
- <b>All your favourite IDE's now available on the cloud</b>
49
- <div>
50
- <sub>
51
- Neverinstall gives you an uninterrupted development experience and improved accessibility,
52
- <br>
53
- allowing you to code faster, better and on-the-go on your favourite IDEs like
54
- <br>
55
- Android Studio, VS Code, Jupyter and PyCharm using your browser.
56
- </sub>
57
- </div>
58
- </a>
59
- <a href="https://neverinstall.com/spaces/devtools?utm_source=github&utm_medium=sponsor&utm_campaign=sindre#gh-dark-mode-only">
60
- <div>
61
- <img src="https://sindresorhus.com/assets/thanks/neverinstall-logo-dark.svg" width="200" alt="neverinstall">
62
- </div>
63
- <br>
64
- <b>All your favourite IDE's now available on the cloud</b>
65
- <div>
66
- <sub>
67
- Neverinstall gives you an uninterrupted development experience and improved accessibility,
68
- <br>
69
- allowing you to code faster, better and on-the-go on your favourite IDEs like
70
- <br>
71
- Android Studio, VS Code, Jupyter and PyCharm using your browser.
72
- </sub>
73
- </div>
74
- </a>
75
- <br>
76
- <br>
77
- <br>
78
43
  <a href="https://www.useanvil.com/?utm_source=sindresorhus#gh-light-mode-only">
79
44
  <div>
80
45
  <img src="https://sindresorhus.com/assets/thanks/anvil-logo-light.svg" width="200" alt="Anvil">
@@ -169,6 +134,7 @@ Click the type names for complete docs.
169
134
  - [`RequireAllOrNone`](source/require-all-or-none.d.ts) - Create a type that requires all of the given keys or none of the given keys.
170
135
  - [`RemoveIndexSignature`](source/remove-index-signature.d.ts) - Create a type that only has explicitly defined properties, absent of any index signatures.
171
136
  - [`PartialDeep`](source/partial-deep.d.ts) - Create a deeply optional version of another type. Use [`Partial<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype) if you only need one level deep.
137
+ - [`PartialOnUndefinedDeep`](source/partial-on-undefined-deep.d.ts) - Create a deep version of another type where all keys accepting `undefined` type are set to optional.
172
138
  - [`ReadonlyDeep`](source/readonly-deep.d.ts) - Create a deeply immutable version of an `object`/`Map`/`Set`/`Array` type. Use [`Readonly<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype) if you only need one level deep.
173
139
  - [`LiteralUnion`](source/literal-union.d.ts) - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. Workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729).
174
140
  - [`Opaque`](source/opaque.d.ts) - Create an [opaque type](https://codemix.com/opaque-types-in-javascript/).
@@ -196,6 +162,7 @@ Click the type names for complete docs.
196
162
  - [`HasOptionalKeys`](source/has-optional-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any optional fields.
197
163
  - [`RequiredKeysOf`](source/required-keys-of.d.ts) - Extract all required keys from the given type.
198
164
  - [`HasRequiredKeys`](source/has-required-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any required fields.
165
+ - [`Spread`](source/spread.d.ts) - Mimic the type inferred by TypeScript when merging two objects using the spread operator.
199
166
 
200
167
  ### JSON
201
168
 
@@ -0,0 +1,70 @@
1
+ import type {BuiltIns} from './internal';
2
+ import type {Merge} from './merge';
3
+
4
+ /**
5
+ @see PartialOnUndefinedDeep
6
+ */
7
+ export interface PartialOnUndefinedDeepOptions {
8
+ /**
9
+ Whether to affect the individual elements of arrays and tuples.
10
+
11
+ @default false
12
+ */
13
+ readonly recurseIntoArrays?: boolean;
14
+ }
15
+
16
+ /**
17
+ Create a deep version of another type where all keys accepting `undefined` type are set to optional.
18
+
19
+ This utility type is recursive, transforming at any level deep. By default, it does not affect arrays and tuples items unless you explicitly pass `{recurseIntoArrays: true}` as the second type argument.
20
+
21
+ Use-cases:
22
+ - Make all properties of a type that can be undefined optional to not have to specify keys with undefined value.
23
+
24
+ @example
25
+ ```
26
+ import type {PartialOnUndefinedDeep} from 'type-fest';
27
+
28
+ interface Settings {
29
+ optionA: string;
30
+ optionB: number | undefined;
31
+ subOption: {
32
+ subOptionA: boolean;
33
+ subOptionB: boolean | undefined;
34
+ }
35
+ };
36
+
37
+ const testSettings: PartialOnUndefinedDeep<Settings> = {
38
+ optionA: 'foo',
39
+ // 👉 optionB is now optional and can be omitted
40
+ subOption: {
41
+ subOptionA: true,
42
+ // 👉 subOptionB is now optional as well and can be omitted
43
+ },
44
+ };
45
+ ```
46
+
47
+ @category Object
48
+ */
49
+ export type PartialOnUndefinedDeep<T, Options extends PartialOnUndefinedDeepOptions = {}> = T extends Record<any, any> | undefined
50
+ ? {[KeyType in keyof T as undefined extends T[KeyType] ? KeyType : never]?: PartialOnUndefinedDeepValue<T[KeyType], Options>} extends infer U // Make a partial type with all value types accepting undefined (and set them optional)
51
+ ? Merge<{[KeyType in keyof T as KeyType extends keyof U ? never : KeyType]: PartialOnUndefinedDeepValue<T[KeyType], Options>}, U> // Join all remaining keys not treated in U
52
+ : never // Should not happen
53
+ : T;
54
+
55
+ /**
56
+ Utility type to get the value type by key and recursively call `PartialOnUndefinedDeep` to transform sub-objects.
57
+ */
58
+ type PartialOnUndefinedDeepValue<T, Options extends PartialOnUndefinedDeepOptions> = T extends BuiltIns | ((...arguments: any[]) => unknown)
59
+ ? T
60
+ : T extends ReadonlyArray<infer U> // Test if type is array or tuple
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;
@@ -0,0 +1,54 @@
1
+ import type {Except} from './except';
2
+ import type {RequiredKeysOf} from './required-keys-of';
3
+ import type {Simplify} from './simplify';
4
+
5
+ type Spread_<FirstType extends object, SecondType extends object> = {
6
+ [Key in keyof FirstType]: Key extends keyof SecondType
7
+ ? FirstType[Key] | Required<SecondType>[Key]
8
+ : FirstType[Key];
9
+ } & Pick<
10
+ SecondType,
11
+ RequiredKeysOf<SecondType> | Exclude<keyof SecondType, keyof FirstType>
12
+ >;
13
+
14
+ /**
15
+ Mimic the type inferred by TypeScript when merging two objects using the spread operator.
16
+
17
+ @example
18
+ ```
19
+ import type {Spread} from 'type-fest';
20
+
21
+ type Foo = {
22
+ a: number;
23
+ b?: string;
24
+ };
25
+
26
+ type Bar = {
27
+ b?: number;
28
+ c: boolean;
29
+ };
30
+
31
+ const foo = {a: 1, b: '2'};
32
+ const bar = {c: false};
33
+ const fooBar = {...foo, ...bar};
34
+
35
+ type FooBar = Spread<Foo, Bar>;
36
+ // type FooBar = {
37
+ // a: number;
38
+ // b?: string | number | undefined;
39
+ // c: boolean;
40
+ // }
41
+
42
+ const baz = (argument: FooBar) => {
43
+ // Do something
44
+ }
45
+
46
+ baz(fooBar);
47
+ ```
48
+
49
+ @category Object
50
+ */
51
+ export type Spread<
52
+ FirstType extends object,
53
+ SecondType extends object,
54
+ > = Simplify<Spread_<FirstType, SecondType>>;