Implement `Pick` in TypeScript

This type challenge is to create your own version of pick (without pick obviously). I decided not to use any utility types

Link to Challenge: https://github.com/type-challenges/type-challenges/blob/main/questions/00004-easy-pick/README.md

Ta…


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Jacob Asper

This type challenge is to create your own version of pick (without pick obviously). I decided not to use any utility types

Link to Challenge: https://github.com/type-challenges/type-challenges/blob/main/questions/00004-easy-pick/README.md

Table Of Contents

  • Pick
    • Table Of Contents
      • Tags
      • Explanation
        • Lookup types
        • Mapped Types
        • Generic Constraints
        • keyof
      • Conclusion
      • Reference

Tags

  • Indexed Access Types/Lookup types
  • Mapped types
  • Generic constraints

Explanation

We need to create a new object type with only the properties in both Type and Union

type MyPick<Type, Union> = /* ... */

Lookup types

To get the type of the keys (keys are also known as indexed access types or lookup types) in Chair, we can use square bracket notation just like accessing a property or method in a JavaScript object

type Chair = {
    color: string,
    legCount: number,
    isComfortable: boolean
}

Chair["color"] // string
Chair["legCount"] // number

Note that only types can be used for indexing

const key = "color"
Chair[key] // Type "key" cannot be used as an index type

Mapped Types

How can we iterate through the union and create a new object type? The answer is mapped types

For example, we can set each key of Chair to a boolean like this with dynamic keys and the in operator

type ChairKeysUnion = "color" | "legCount" | "isComfortable"

type BooleanChair = {
    [Key in ChairKeysUnion]: boolean
} 
/*
type BooleanChair = {
    color: boolean;
    legCount: boolean;
    isComfortable: boolean;
}
*/

Note that Key in this example is a parameter, so it is just a placeholder name. It could be called Property or Jimothy and work just as well

Generic Constraints

But why can't we just combine mapped types and lookup types to set each property in the union to the appropriate lookup type like this?

type MyPick<Type, Union> = {
    [Key in Union]: Type[Key]
}

At this point, MyPick is not typesafe—it accepts any and all properties in Union. In the case a property doesn't exist in the Type passed to MyPick, it will be on the new object type with a value of unknown

type NewChair = MyPick<Chair, 'color' | 'isComfortable' | 'invalid'>
/*
type NewChair = {
    color: string;
    isComfortable: boolean;
    invalid: unknown;
}*/
keyof

To limit Union to only lookup types in Type, we first need Type's lookup types. To do this, we can use the keyof operator. It takes an object type and returns a string, string union, or number union of the type's keys.

type Chair = {
    color: string,
    legCount: number,
    isComfortable: boolean
}

type ChairIndexUnion = keyof Chair // "color" | "legCount" | "isComfortable"

Now that we have both unions, we can constrain the Union parameter to lookup types in Type with the extends keyword

type MyPick<Type, Union extends keyof Type> = {
    [Key in Union]: Type[Key]
}

type NewChair = MyPick<Chair, 'color' | 'isComfortable' | 'invalid'>
/*
Type '"color" | "isComfortable" | "invalid"' does not satisfy the constraint 'keyof Chair'.
Type '"invalid"' is not assignable to type 'keyof Chair'.
*/

invalid is not in Chair, so the NewChair type is invalid

Conclusion

Congratulations—you now have a typesafe pick function!

Reference


This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Jacob Asper


Print Share Comment Cite Upload Translate Updates
APA

Jacob Asper | Sciencx (2022-12-22T00:28:48+00:00) Implement `Pick` in TypeScript. Retrieved from https://www.scien.cx/2022/12/22/implement-pick-in-typescript/

MLA
" » Implement `Pick` in TypeScript." Jacob Asper | Sciencx - Thursday December 22, 2022, https://www.scien.cx/2022/12/22/implement-pick-in-typescript/
HARVARD
Jacob Asper | Sciencx Thursday December 22, 2022 » Implement `Pick` in TypeScript., viewed ,<https://www.scien.cx/2022/12/22/implement-pick-in-typescript/>
VANCOUVER
Jacob Asper | Sciencx - » Implement `Pick` in TypeScript. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/12/22/implement-pick-in-typescript/
CHICAGO
" » Implement `Pick` in TypeScript." Jacob Asper | Sciencx - Accessed . https://www.scien.cx/2022/12/22/implement-pick-in-typescript/
IEEE
" » Implement `Pick` in TypeScript." Jacob Asper | Sciencx [Online]. Available: https://www.scien.cx/2022/12/22/implement-pick-in-typescript/. [Accessed: ]
rf:citation
» Implement `Pick` in TypeScript | Jacob Asper | Sciencx | https://www.scien.cx/2022/12/22/implement-pick-in-typescript/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.