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
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
}
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 }
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>;
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.
Top comments (8)
**palmface**
I was strictly trying to touch only the line offunction takeSomeTypeOnly
.These challenges are really nice, but please be specific with what we can and cannot do. D:
// change below function type definition 🔥 in order to allow only strict SomeType value
I might be the one misunderstanding.
Thanks anyway! Your exercises keep my brain running
you can do it in one line
Nice try. Don't work.
Thanks for the comment. Sorry if smth was not clear.
Thanks for the answers Maciej.
However the first solution doesn't complain 😢 if i use this input -
Good hack Rahul. Unfortunately you can also do the same for all these solution and hack them. I don't think it is possible to prevent such, in the same way we can hack almost every type by
as any as X
thing.In any way I think the wanted behavior was achieved, even though we can hack it, the hack is explicitly visible in the code.
But thanks for the comment!
Cool stuff! I'm liking the series! It's getting advanced
thank you, these are advanced indeed 🔥🔥 and super interesting :)