PartialByKeys
Challenge
Implement a generic PartialByKeys<T, K>
which takes two type arguments T
and
K
.
K
specifies the set of properties of T
that should be set to optional. When
K
is not provided, it should make all properties optional just like the normal
Partial<T>
.
Solution
Okay, let’s break down the challenge into three parts.
- Extract all the properties of
T
which are present inK
and mark them optional. - Extract all the properties of
T
which are not present inK
and keep them as is. - Merge both of the types mentioned above to get the answer.
Okay, how do we create a new type by picking all the properties from T
except
K
?
That’s right. We can use the Omit
type utility exposed by TypeScript or create
our own Omit type helper.
type MyOmit<F, S> = { [P in keyof F as P extends S ? never : P]: F[P] };
type EverythingFromTExceptK<T, K> = MyOmit<T, K>;
Now let’s extract all the properties from K
present in T
and mark them
optional. We can do so by using
mapped types.
type OptionalProperties<T, K> = {
[P in keyof T as P extends K ? P : never]?: T[P];
};
Pretty amazing right? Now that we have both parts of our solution, let’s merge them.
type PartialByKeys<T, K = keyof T> = OptionalProperties<T, K> &
EverythingFromTExceptK<T, K>;
Note that this still does not solve our problem. Taking a closer look at the
generated type, we can see PartialByKeys
spits out
{...properties} & {...some other properties}
. So to reach our final answer, we
will have to merge both the types into one singular type.
type MyMerge<T> = { [P in keyof T]: T[P] };
type PartialByKeys<T, K = keyof T> = MyMerge<
OptionalProperties<T, K> & EverythingFromTExceptK<T, K>
>;
Comments