type-fest 2.18.0 → 2.18.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "2.18.0",
3
+ "version": "2.18.1",
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
@@ -162,7 +162,7 @@ Click the type names for complete docs.
162
162
  - [`HasOptionalKeys`](source/has-optional-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any optional fields.
163
163
  - [`RequiredKeysOf`](source/required-keys-of.d.ts) - Extract all required keys from the given type.
164
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.
165
+ - [`Spread`](source/spread.d.ts) - Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.
166
166
 
167
167
  ### JSON
168
168
 
@@ -67,25 +67,24 @@ type Jsonify<T> =
67
67
  // Note: The use of tuples in this first condition side-steps distributive conditional types
68
68
  // (see https://github.com/microsoft/TypeScript/issues/29368#issuecomment-453529532)
69
69
  [Extract<T, NotJsonable | bigint>] extends [never]
70
- ? T extends PositiveInfinity | NegativeInfinity ? null
71
- : T extends JsonPrimitive
72
- ? T // Primitive is acceptable
73
- : T extends Number ? number
74
- : T extends String ? string
75
- : T extends Boolean ? boolean
76
- : T extends Map<any, any> | Set<any> ? {}
77
- : T extends TypedArray ? Record<string, number>
78
- : T extends Array<infer U>
79
- ? Array<Jsonify<U extends NotJsonable ? null : U>> // It's an array: recursive call for its children
80
- : T extends object
81
- ? T extends {toJSON(): infer J}
82
- ? (() => J) extends (() => JsonValue) // Is J assignable to JsonValue?
83
- ? J // Then T is Jsonable and its Jsonable value is J
84
- : never // Not Jsonable because its toJSON() method does not return JsonValue
85
- : {[P in keyof T as P extends symbol
86
- ? never
87
- : T[P] extends NotJsonable
88
- ? never
89
- : P]: Jsonify<Required<T>[P]>} // It's an object: recursive call for its children
90
- : never // Otherwise any other non-object is removed
70
+ ? T extends PositiveInfinity | NegativeInfinity ? null
71
+ : T extends JsonPrimitive ? T // Primitive is acceptable
72
+ : T extends object
73
+ // Any object with toJSON is special case
74
+ ? T extends {toJSON(): infer J} ? (() => J) extends (() => JsonValue) // Is J assignable to JsonValue?
75
+ ? J // Then T is Jsonable and its Jsonable value is J
76
+ : never // Not Jsonable because its toJSON() method does not return JsonValue
77
+ // Instanced primitives are objects
78
+ : T extends Number ? number
79
+ : T extends String ? string
80
+ : T extends Boolean ? boolean
81
+ : T extends Map<any, any> | Set<any> ? {}
82
+ : T extends TypedArray ? Record<string, number>
83
+ : T extends any[]
84
+ ? {[I in keyof T]: T[I] extends NotJsonable ? null : Jsonify<T[I]>}
85
+ : {[P in keyof T as P extends symbol ? never
86
+ : T[P] extends NotJsonable ? never
87
+ : P
88
+ ]: Jsonify<Required<T>[P]>} // Recursive call for its children
89
+ : never // Otherwise any other non-object is removed
91
90
  : never; // Otherwise non-JSONable type union was found not empty
@@ -2,7 +2,7 @@ import type {Except} from './except';
2
2
  import type {RequiredKeysOf} from './required-keys-of';
3
3
  import type {Simplify} from './simplify';
4
4
 
5
- type Spread_<FirstType extends object, SecondType extends object> = {
5
+ type SpreadObject<FirstType extends object, SecondType extends object> = {
6
6
  [Key in keyof FirstType]: Key extends keyof SecondType
7
7
  ? FirstType[Key] | Required<SecondType>[Key]
8
8
  : FirstType[Key];
@@ -11,8 +11,17 @@ type Spread_<FirstType extends object, SecondType extends object> = {
11
11
  RequiredKeysOf<SecondType> | Exclude<keyof SecondType, keyof FirstType>
12
12
  >;
13
13
 
14
+ type TupleOrArray = readonly [...unknown[]];
15
+
16
+ type SpreadTupleOrArray<
17
+ FirstType extends TupleOrArray,
18
+ SecondType extends TupleOrArray,
19
+ > = Array<FirstType[number] | SecondType[number]>;
20
+
21
+ type Spreadable = object | TupleOrArray;
22
+
14
23
  /**
15
- Mimic the type inferred by TypeScript when merging two objects using the spread operator.
24
+ Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.
16
25
 
17
26
  @example
18
27
  ```
@@ -46,9 +55,31 @@ const baz = (argument: FooBar) => {
46
55
  baz(fooBar);
47
56
  ```
48
57
 
58
+ @example
59
+ ```
60
+ import type {Spread} from 'type-fest';
61
+
62
+ const foo = [1, 2, 3];
63
+ const bar = ['4', '5', '6'];
64
+
65
+ const fooBar = [...foo, ...bar];
66
+ type FooBar = Spread<typeof foo, typeof bar>;
67
+ // FooBar = (string | number)[]
68
+
69
+ const baz = (argument: FooBar) => {
70
+ // Do something
71
+ };
72
+
73
+ baz(fooBar);
74
+ ```
75
+
49
76
  @category Object
50
77
  */
51
78
  export type Spread<
52
- FirstType extends object,
53
- SecondType extends object,
54
- > = Simplify<Spread_<FirstType, SecondType>>;
79
+ FirstType extends Spreadable,
80
+ SecondType extends Spreadable,
81
+ > = FirstType extends TupleOrArray
82
+ ? SecondType extends TupleOrArray
83
+ ? SpreadTupleOrArray<FirstType, SecondType>
84
+ : Simplify<SpreadObject<FirstType, SecondType>>
85
+ : Simplify<SpreadObject<FirstType, SecondType>>;