Advanced TypeScript Exercises - Answer 7

Pragmatic Maciej - Mar 13 '20 - - Dev Community

The question was about exclusive behavior of the type. The core thing is to understand is the never type. Never is an bottom type, so type which has no values, like an empty set. In other words - we cannot assign anything to the type never.

const x: never = šŸ•³ // there is no possible value to make compiler happy
Enter fullscreen mode Exit fullscreen mode

We will use never in order to achieve the wanted exclusive type behavior.

Answer 7.1 - type which will allow only for a empty object value

type EmptyObject = {
    [K in PropertyKey]: never
}
Enter fullscreen mode Exit fullscreen mode

EmptyObject type is a mapped type, which for every key has value type never. Every key here is represented by K in PropertyKey as PropertyKey represents all possible keys of objects. We could be using [K in any] with the same effect. In result our type for every key allows the value to be never, therefor there is no possibility to put any key into the object, as we have no instance of never bottom type.

Answer 7.2 - change function type to be exclusive for its argument

type Exclusive<T1, T2 extends T1> = {
    [K in keyof T2]: K extends keyof T1 ? T2[K] : never 
}
function takeSomeTypeOnly<T extends SomeType>(x: Exclusive<SomeType, T>) { return x }
Enter fullscreen mode Exit fullscreen mode

In the solution we again are using mapped type, we say that argument is something which extends SomeType and we put it into Exclusive type level function which is doing the needed transformation. Exactly [K in keyof T2]: K extends keyof T1 ? T2[K] : never, so for every key in T2 we check if this key is also in T1(the wanted type) if it is we pass it, if not we put never, it means that such property will always be invalid.

Alternative version of Exclusive can look like that:

type Exclusive<T1, T2 extends T1> = T2 & Record<Exclude<keyof T2, keyof T1>, never>;
Enter fullscreen mode Exit fullscreen mode

We use Record utility type and Exclude utility type in order to make mapped type with all keys invalid for T1 so with never value type. Joining it with T1 gives us the same result - keys which are not in wanted type have never value.

The full code can be found - The Playground

Thank you Manolo Edge for the good answer and taking the challenge.

This series will continue. If you want to know about new exciting questions from advanced TypeScript please follow me on dev.to and twitter.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player