Experimentalimport type {MergeDeep} from 'type-fest';
type Foo = {
life: number;
items: string[];
a: {b: string; c: boolean; d: number[]};
};
interface Bar {
name: string;
items: number[];
a: {b: number; d: boolean[]};
}
type FooBar = MergeDeep<Foo, Bar>;
// {
// life: number;
// name: string;
// items: number[];
// a: {b: number; c: boolean; d: boolean[]};
// }
type FooBar = MergeDeep<Foo, Bar, {arrayMergeMode: 'spread'}>;
// {
// life: number;
// name: string;
// items: (string | number)[];
// a: {b: number; c: boolean; d: (number | boolean)[]};
// }
import type {MergeDeep} from 'type-fest';
// Merge two arrays
type ArrayMerge = MergeDeep<string[], number[]>; // => (string | number)[]
// Merge two tuples
type TupleMerge = MergeDeep<[1, 2, 3], ['a', 'b']>; // => (1 | 2 | 3 | 'a' | 'b')[]
// Merge an array into a tuple
type TupleArrayMerge = MergeDeep<[1, 2, 3], string[]>; // => (string | 1 | 2 | 3)[]
// Merge a tuple into an array
type ArrayTupleMerge = MergeDeep<number[], ['a', 'b']>; // => (number | 'b' | 'a')[]
import type {MergeDeep, MergeDeepOptions} from 'type-fest';
type Foo = {foo: 'foo'; fooBar: string[]};
type Bar = {bar: 'bar'; fooBar: number[]};
type FooBar = MergeDeep<Foo, Bar>;
// { foo: "foo"; bar: "bar"; fooBar: number[]}
type FooBarSpread = MergeDeep<Foo, Bar, {arrayMergeMode: 'spread'}>;
// { foo: "foo"; bar: "bar"; fooBar: (string | number)[]}
type FooBarArray = MergeDeep<Foo[], Bar[]>;
// (Foo | Bar)[]
type FooBarArrayDeep = MergeDeep<Foo[], Bar[], {recurseIntoArrays: true}>;
// FooBar[]
type FooBarArraySpreadDeep = MergeDeep<Foo[], Bar[], {recurseIntoArrays: true; arrayMergeMode: 'spread'}>;
// FooBarSpread[]
type FooBarTupleDeep = MergeDeep<[Foo, true, 42], [Bar, 'life'], {recurseIntoArrays: true}>;
// [FooBar, 'life', 42]
type FooBarTupleWithArrayDeep = MergeDeep<[Foo[], true], [Bar[], 'life', 42], {recurseIntoArrays: true}>;
// [FooBar[], 'life', 42]
import type {MergeDeep, MergeDeepOptions} from 'type-fest';
function mergeDeep<Destination, Source, Options extends MergeDeepOptions = {}>(
destination: Destination,
source: Source,
options?: Options,
): MergeDeep<Destination, Source, Options> {
// Make your implementation ...
}
This type is marked as experimental because it depends on ConditionalSimplifyDeep which itself is experimental.
Merge two objects or two arrays/tuples recursively into a new type.