UNPKG

1.81 kBTypeScriptView Raw
1import type {Except} from './except';
2import type {RequiredKeysOf} from './required-keys-of';
3import type {Simplify} from './simplify';
4
5type SpreadObject<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<
10SecondType,
11RequiredKeysOf<SecondType> | Exclude<keyof SecondType, keyof FirstType>
12>;
13
14type TupleOrArray = readonly [...unknown[]];
15
16type SpreadTupleOrArray<
17 FirstType extends TupleOrArray,
18 SecondType extends TupleOrArray,
19> = Array<FirstType[number] | SecondType[number]>;
20
21type Spreadable = object | TupleOrArray;
22
23/**
24Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.
25
26@example
27```
28import type {Spread} from 'type-fest';
29
30type Foo = {
31 a: number;
32 b?: string;
33};
34
35type Bar = {
36 b?: number;
37 c: boolean;
38};
39
40const foo = {a: 1, b: '2'};
41const bar = {c: false};
42const fooBar = {...foo, ...bar};
43
44type FooBar = Spread<Foo, Bar>;
45// type FooBar = {
46// a: number;
47// b?: string | number | undefined;
48// c: boolean;
49// }
50
51const baz = (argument: FooBar) => {
52 // Do something
53}
54
55baz(fooBar);
56```
57
58@example
59```
60import type {Spread} from 'type-fest';
61
62const foo = [1, 2, 3];
63const bar = ['4', '5', '6'];
64
65const fooBar = [...foo, ...bar];
66type FooBar = Spread<typeof foo, typeof bar>;
67// FooBar = (string | number)[]
68
69const baz = (argument: FooBar) => {
70 // Do something
71};
72
73baz(fooBar);
74```
75
76@category Object
77*/
78export type Spread<
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>>;