Advanced TypeScript Exercises - Answer 10
Tags: typescript, challenge, javascript, webdev
Published: 2020-11-02 11:03:34

--- series: Advanced TypeScript Exercises ---

I've asked how to make different **&** operation by custom **Merge** type level function.

> **Note** - if you don't recall what means - type level function please take a moment for reading - [typescript is more than you think](https://dev.to/macsikora/typescript-is-more-than-you-think-2nbf).

### Solution 1 - Mapped Type ###
```ts
type Merge<A, B> = {
    [K in keyof A | keyof B]: 
        K extends keyof B ? B[K] : 
        K extends keyof A ? A[K] : never
}
```
What we are doing here is creating function **Merge** which is a [mapped type](https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types). Mapped type allows for iteration over one type and mapping it into another type. 

- `[K in keyof A | keyof B]` - we iterate over union of keys from both types A and B, union will remove repeating keys in both types, so iteration will not need to go through them twice
- `K extends keyof B ? B[K] : 
        K extends keyof A ? A[K] : never` - we use [conditional type](https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types) in order to check if our current key belongs to key of type B, if no, we check if it belongs to type A, if not belongs to any of these, what is not possible, we fallback to `never`.

> **Note** pay attention that we check firstly B type, so if the key is in B, we take value from B, it means we will overwrite eventual value from type A. Don't worry though, that was the requirement of the task.

> **Note** I said that there is no possibility that key will not be either in A or B, because we iterate over `keyof A | keyof B`, so there is no option that key will not belong to any of them.

### Solution 2 - Using Omit ###

```ts
type Merge<A, B> = Omit<A, keyof B> & B; 
```
Yes that is the whole solution 😉. TypeScript type level standard library gives us functions like [Omit](https://www.typescriptlang.org/docs/handbook/utility-types.html) which is really just mapped type as we did in the solution 1. So if there is ready to use function why not to use it?

- `Omit<A, keyof B>` we make type which contains only keys of A which are not in B
- `Omit<A, keyof B> & B` - we merge B type to already created type which has no intersection with B as keys of B where removed from A.

In result we have done the same thing as in previous solution,but with one line of code.

Special thanks for [SirMoustache](https://dev.to/sirmoustache/comment/1761h), [hnicolas](https://dev.to/hnicolas/comment/175jm) and others for their great answers in [comments](https://dev.to/macsikora/advanced-typescript-exercises-question-10-2n93/comments). You can find both solution [in the playground](https://www.typescriptlang.org/play?#code/PTAEBcFMGd1ATAhuRAocBPADpUANUUAXlAG9VDDEAuUARgsoCNaA7AVwFsnIAnVAL6p02XAE1iZRlVoAmaaBahYvAJasA5goDGtJgHt9AG0iJWg1CFABaW3fsPHTh6ADKAeQAyAVQAqASXcAOXpnMOdUUlARHFAAWT4NSAAeAEEAGlAAIQA+SXJKUABtAGlQdVAAa0gMfQAzUFTQAB8qmvrsgF1aBUKyyAAPKFZ4aDbahqzQAH5s0s7QHsK+0EHh0fGOptnU+cXQVkgANz5BUCsACz5cWvZeZWN2cFV9VlBAXg3AUl3hTFjfGHAdEkqWg0D44GSCV4SWSeEyYhymVINFAskyShU6g0mV0ikMJjMAjyVn+sGUF307CM8FAWEQoJsoE4plYYx4oFJgPJlOpilw4F47EgMVwnNkwNB4MhiRSyOoAHJEExtPL0WwuDxeAIkSj5fBIHV5USdbQ9QbVYp1dw+ETzmBOdyqTS6QzrEyWWzRQDxdAKU6+RBBcKhJYwOFwxG3F4-IEQrIIwnItFfrgoTCMtk8iR3JxVBCM9UJpnQAAybJ20BXXg3Sn3aCPZ6vD7fEUcgFAkggsG8CFplJw0AIk2otXKAVYnF6fEs20kgGO3kusZu5lmT1t2BA308mnsgVC1tiiXd3sy5JyxXKi1KDjWrXDs2G41kXX6w2j2+a2f2+fb-1LxlV1ZAMjz-Xk9yDCxhGgmDYKsBMEMTKwnlUIw8wwUA6n0e4oFgLEICuUBq2gKlwFDcpwDGVh9DgasjGQSAaXAfQCNwABHIU8KbVQxleIwMKwnDf3YPNhRTRpJR7ZJGF8Oh0hktFGAAfQAYSubRKg7DkgTWSARjGXxxVmfdcFoOpECMMF5MIVT1MqcUSEM1Yhj0jZZJmQMhX2czLOFQgckYEgfLBZz1jGWzIA0oFZmC0zMIskLdP00AIo0oz4t8-YTKAA).
 

**This series will continue**. If you want to know about new exciting questions from advanced TypeScript please follow me on [dev.to](https://dev.to/macsikora) and [twitter](https://twitter.com/macsikora).