3

Type Challenges: Implement the PartialByKeys<T, K> Utility Type

 1 year ago
source link: https://blog.bitsrc.io/typescript-challenges-implement-the-partialbykeys-t-k-utility-type-21b2780ef48d
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Type Challenges: Implement the PartialByKeys<T, K> Utility Type

The Built-In Partial Generic Are Not Flexible, the PartialByKeys Generics Come to the Rescue.

1*uUDXL6wG2eg8sqVHGIccxw.jpeg

Welcome to the Mastering TypeScript series, there are dozens of articles in this series. To help readers better consolidate their knowledge of TypeScript, I have selected a few dozen challenges from the type-challenges repository on Github to complete the type challenge with you.

Challenge

Implement a generic PartialByKeys<T, K> which takes two type argument T and K.

K specify the set of properties of T that should set to be optional. When K is not provided, it should make all properties optional just like the normal Partial<T>.

For example:

interface User {
name: string
age: number
address: string
}type UserPartialName = PartialByKeys<User, 'name'>
// { name?:string; age:number; address:string }

Solution

Our type challenge is to implement the PartialByKeys<T, K> generic, When K is not provided, it should make all properties optional just like the normal Partial<T>. So let’s first understand what Partial<T> generic does.

Partial<T>

Constructs a type with all properties of Type set to optional.

1*Ga_D3VCLdvHhSZJ3-JRBNw.jpeg

Partial<T> is TypeScript’s built-in utility type, which is defined in the typescript/lib/lib.es5.d.ts file:

/**
* Make all properties in T optional.
* typescript/lib/lib.es5.d.ts
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
1*qhvW4fB-g-RXVGvhYakabg.gif
1*mCJWHhUzde3qE4v6rYS_Dw.jpeg

The Partial<T> generic uses TypeScript’s mapped type internally, and its syntax is as follows:

1*7iuvURZie0JxNSmuAQe94w.jpeg

Where P in K is similar to the JavaScript for...in statement, which is used to iterate through all types in type K, and the type variable T, which is used to represent any type in TypeScript.

1*YK9f_jV3ETabwSDqHUSCmQ.gif

You can also use the additional modifiers read-only and question mark (?) in the mapping process. The corresponding modifiers are added and removed by adding the plus(+) and minus(-) prefixes. The default is to use the plus sign if no prefix is added.

After introducing the relevant knowledge of mapped types, the idea of ​​​​implementing the PartialByKeys<T, K> generic is very simple.

1*bwM4NTXhOAMoF6lIwnVjhw.jpeg

As can be seen from the above figure, we only need to select the properties associated with K, set them as optional and generate a new object type, then build another object type based on the remaining properties, and finally use the & operator to convert the above two object types are combined into a new object type.

If you want to learn more about intersection types, you can read this article.

Complete code

Finally, let’s look at the complete code:

TypeScript 4.1 allows us to remapping keys in mapped types using the as clause. Its syntax is as follows:

type MappedTypeWithNewKeys<T> = {
[K in keyof T as NewKeyType]: T[K]
// ^^^^^^^^^^^^^
// New Syntax!
}

where the type of the NewKeyType must be a subtype of the string | number | symbol union type. In the process of remapping the keys, we can filter the keys by returning the never type.

1*H48m3WbCuf1t7tzoTTm_hw.jpeg

The role of the Merge generic is to merge object types. In addition to the above solutions, there is a more concise way.

type PartialByKeys<T, K = keyof T> = Merge<
{
[P in keyof T as P extends K ? P : never]?: T[P]
} & Pick<T, Exclude<keyof T, K>
>

In the above code, we are using TypeScript’s built-in Pick utility type, if you want to learn more about this generic type, you can read the following article:

The main knowledge involved in this challenge is TypeScript’s mapped types. If you want to learn more about mapped types, you can read the following article:

If you have other solutions, you can give me a message. you also can follow me on Medium or Twitter to read more about TS and JS!

Resources

Build apps with reusable components like Lego

1*mutURvkHDCCgCzhHe-lC5Q.png

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK