This time we want to implement a type in TypeScript that returns us a type with all required fields of an object:

```
type I = GetRequired<{ foo: number, bar?: string }>
// expected to be { foo: number }
```

## Intersection with undefined

Let’s build this step by step. What types are actually behind *foo* and *bar*? It looks as follows:

```
number // foo is obviously of type number
string | undefined // for bar we can either use string or undefined
```

An optional field basically means that the possible types are the defined type (*string*) or *undefined*. So, we need some way to detect something that can be *undefined*. We would like to do this with an intersection. Then we could later on check with extends. Think about the following two types:

**type **testFoo = **number **& **undefined**;
**type **testBar = (**string **| **undefined**) & **undefined**

An intersection of number & undefined can never happen, the type sets have no common elements. It’s different for the second case though. If we intersect *(string | undefined)* with *undefined*, the common type set is the one that contains just *undefined*. Our IDE helps us here as well:

What have we learnt so far? An optional field can be of a certain type or *undefined*. And intersection of something containing *undefined* with *undefined* itself results in *undefined*.

## Looping through keys and checking intersection

Now let’s build the whole thing starting with the simple “key/value” type defined like:

**type **KeysAndValues<T> = {
[K **in keyof **T]: T[K]
}
// So, nothing else than { foo: number, bar?: string }

Now let’s filter out *bar?* with the help of the intersection with *undefined*:

**type **II<T> = {
[K **in keyof **T]: T[K] & **undefined extends never **? K : **never**;
}

If the intersection with *undefined* extends *never*, we return the key K. In the other cases we return *never*. This leaves us with the following:

**type **IIa = II<{ foo: **number**, bar?: **string **}>;
// equal to { foo: "foo"; bar?: undefined; }

The left hand side of *II<T>* gives us just all the keys with *[K in keyof T]*. On the right hand side:

- the intersection for
*foo*extends*never*and therefore we return*K*which is in this case the key “foo” - for
*bar*the intersection with*undefined*doesn’t extend never. So, we return*never*which leaves us with*undefined*in*IIa*

## Putting everything together

At this moment we can determine the keys for required fields:

**type **RequiredKey<T> = {
[K **in keyof **T]: T[K] & **undefined extends never **? K : **never**;
}[**keyof **T];
**type **requiredKeysForI = RequiredKey<{ foo: **number**, bar?: **string **}>;
// "foo" | undefined

The expression *{ foo: “foo”; bar?: undefined; }* accessed via keys *[keyof T]* gives *“foo” | undefined*.

Finally, we can use the required keys to construct the type:

**type **GetRequired<T> = {
[K **in **RequiredKey<T>]: T[K];
};

If we only loop through the required keys, we only get *foo*. So, this finally leaves us with:

**type **I = GetRequired<{ foo: **number**, bar?: **string **}>

Our IDE shows us that we have found a good type to reduce something to the required fields in TypeScript:

If you’re interested in a type for chainable options, check out this post.