DEV Community

Cover image for TS Challenge - Merge
DevJoseManuel
DevJoseManuel

Posted on • Updated on

TS Challenge - Merge

In this post we are going to try to solve the following TypeScript challenge taken from Merge Challenge

Merge two types into a new type. Keys of the second type overrides keys of the first type.

The first thing we have to understand is that the type that we are going to obtain is an object, so in the first approximation what we do is to indicate it. So, if F and S represents objects we can write:

type Merge<F, S> = {}
Enter fullscreen mode Exit fullscreen mode

Graphically we can represent these types as follows:

types  raw `F` endraw  and  raw `S` endraw

Now we have to keep the attributes of the first and the second of the generics that we are receiving. This is achieved by using the keyof operator. Now, how do we get the attributes of F? Well, simply by writing

[P in keyof F]
Enter fullscreen mode Exit fullscreen mode

which is something like "create an index that consists of all the attributes that are part of the generic F and store them in the generic P eliminating those that are duplicated".

 raw `[P in keyof F]` endraw

But, how do we add the attributes of S? Well, this is where we have to use the union type to obtain all the attributes that are in both objects. Therefore we will write where we assign to each of the new attributes the value never because in the end what we need is a type with a value:

type Merge<F, S> = {
  [P in keyof F | keyof S]: never
}
Enter fullscreen mode Exit fullscreen mode

Therefore, at this point what we have is something like what is shown in the following figure:

 raw `[P in keyof F | keyof S]` endraw

Now we simply need to determine the value that will be assigned to the attribute in question. According to the statement of the challenge if the attribute belongs to the second generic then that will be its value while if it belongs to the first it will be that of the first and in the case that it is neither of the two then we will return never.

How can we know if an attribute belongs to an object in TypeScript? Well, thanks to the use of the clause extends (https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#in-extends-clause) in such a way that if we take the data type that is formed by all the attributes of the second type S(that we already know that it is obtained as keyof S) to know if one of the attributes belongs to the same one we will have to write something like the following:

[P in keyof F | keyof S]: P extends keyof S
Enter fullscreen mode Exit fullscreen mode

In other words, we have constructed the data type that is the union of the attributes of F and S and we have named it P. Now what we simply do is to see if the attribute P belongs to the set of S attributes.

Now we can make use of the Conditional Type that TypeScript offers us so that if it is an attribute of S we will keep it and otherwise we will check if it is of the first type.

But what do we have to do to keep the type of the attribute? Well, just access it in the typing of S. How? Very simple using the operator []. That is, if you want to access an attribute of S you would write something like S['attribute']. Since the attribute that passes the condition is Pwe simply access it in type S. In case it is not we will assign never to it:

type Merge<F, S> = {
  [P in keyof F | keyof S]: P extends keyof S ? S[P] : never
}
Enter fullscreen mode Exit fullscreen mode

If we repeat this process but this time seeing if the attribute is declared in F to assign its value or if not what we do is to assign it never since for whatever reason the attribute is not part of any of the objects (which is impossible but so that TypeScript does not give errors we have to complete the conditional operator).

This leaves us with the following result for the challenge:

type Merge<F, S> = {
  [P in keyof F | keyof S]: P extends keyof S
    ? S[P] 
    : P extends keyof F
      ? F[P]
      : never
}
Enter fullscreen mode Exit fullscreen mode

Now if we go to run the result of our challege to see if we have errors or not we will see that all the tests shown will pass correctly so the proposed solution is correct.

Checking the solution

Top comments (0)