Mann schreibt Text an Laptop
Sven, Kiya | 12.01.2024

Merging Types in TypeScript

Web > Merging Types in TypeScript

Merging Types in TypeScript

Consider the following types in TypeScript:

1type ObjA = {
2  propA: string;
3  propB: string;
4}
5
6type ObjB = {
7  propA: number;
8  propC: number;
9}

What if you want to create a type combining those two? A first approach could simply be using the union operator:

1type CombinedAB = ObjA | ObjB

This results in a Record type having all three properties propA, propB and propC. However, you can ask yourself about the type of these properties? Surely propB is of type string and propC is of type number, but what about propA? Ideally it should result in string | number but in fact it's only string. So using the union operator does not merge the inner types of a Record it just takes the first type it finds for properties with the same name. type CombinedBA = ObjB | ObjA would result in propA being of type number.

1const combined: CombinedAB = {
2  propA: 123, // => TypeError: propA is of type string
3  propB: 'hello world!',
4  propC: 3.14159,
5}

But what if we want to combine (or union) the types of a Record's property? Here is a simple helper type for achieving that:

1type Merge<A, B> = {
2    [K in keyof A | keyof B]: K extends keyof A
3    ? K extends keyof B
4        ? A[K] | B[K]
5        : A[K]
6    : K extends keyof B
7        ? B[K]
8        : never;
9};
10
11type Merged = Merge<ObjA, ObjB>;
12// result => { propA: string | number, propB: string, propC: number } 

At first this looks very cryptic but it's actually quite simple. At the root level it is an index type (they look like this { [s: string]: any }). Now the keys of the new type have to be a union of the keys of the two base types so that the resulting type has every property from it's base types. Determining the types of the values now is just checking if the key K is found in one or both of the base types using some ternary expressions. With this type we can create objects where the property types are unioned:

1const combinedA: CombinedAB = {
2  propA: 123, // totally fine now
3  propB: 'hello world!',
4  propC: 3.14159,
5}
6
7const combinedB: CombinedAB = {
8  propA: 'I can be a string', // and this still works
9  propB: 'hello world!',
10  propC: 3.14159,
11}

By understanding TypeScript’s type system, one can make good use of it and avoid many common errors that could make it to production otherwise.

Content
  • What is the impact of using the union operator in TypeScript?
  • How to combine the types of a Record's property?
  • What is meant by index type in TypeScript?
Sven Röttering
Sven (Softwareentwickler)

… ist sachkundiger Full-Stack Entwickler mit unglaublich vielseitigem Kenntnisprofil. Er arbeitet am liebsten mit Java, TypeScript und NestJS, und kennt sich nicht nur mit Angular und React aus. Er le... mehr anzeigen

Github
Kiya

... ist unsere engagierte und leidenschaftliche Künstliche Intelligenz und Expertin für Softwareentwicklung. Mit einem unermüdlichen Interesse für technologische Innovationen bringt sie Enthusiasmus u... mehr anzeigen

Standort Hannover

newcubator GmbH
Bödekerstraße 22
30161 Hannover

Standort Dortmund

newcubator GmbH
Westenhellweg 85-89
44137 Dortmund