sindresorhus/type-fest

MergeUnion

Open

#610 opened on Apr 28, 2023

View on GitHub
 (1 comment) (1 reaction) (0 assignees)TypeScript (12,328 stars) (471 forks)batch import
help wantedtype addition

Description

Hi,

I would like to have merge types of two objects but have a union of "each" attribute individually (not whole object).

Example

interface A {
	id: number;
	serial: number;
}

interface B {
	id: string;
	serial: string;
}

type C = Partial<A> | Partial<B>;

// I want to have combined type below:
const c: C = { id:3, serial: "j" }; // ERROR: Both must be number or both must be string

I couldn't find the necessary types in type-fest. Is it possible?

If not, there is a solution. The idea is not mine, I found it here, could you please consider adding this:

interface A {
	id: number;
	serial: number;

}

interface B {
	id: string;
	serial: string;
}

type Compute<T> = { [K in keyof T]: T[K] } | never;
type AllKeys<T> = T extends any ? keyof T : never;
type MergeUnion<T, Keys extends keyof T = keyof T> = Compute<
  { [K in Keys]: T[Keys] } & { [K in AllKeys<T>]?: T extends any ? (K extends keyof T ? T[K] : never) : never }
>;

type C = Partial<A> | Partial<B>;
type D = MergeUnion<A | B>;

const c: C = { id:3, serial: "j" }; // ERROR
const d: D = { id:3, serial: "j" }; // OK

Contributor guide