Skip to content

Latest commit

 

History

History
97 lines (71 loc) · 2.32 KB

notes.md

File metadata and controls

97 lines (71 loc) · 2.32 KB

Pick

This challenge is to recreate the TS core library utility type Pick<Type, Keys> which:

Constructs a type by picking the set of properties Keys (string literal or union of string literals) from Type.

For example, suppose we have the following Car type:

type Car = {
  make: string
  model: string
  price: number
}

We can create a new type CarWithoutPrice by picking some of Car's properties:

type CarWithoutPrice = Pick<Car, 'make' | 'model'>

const car: CarWithoutPrice = {
  make: 'tesla',
  model: '3',
}

Solution

To solve this we can use the keyof type operator in combination with Mapped types.

keyof

The keyof operator takes an object type and produces a string or numeric literal union of its keys.

Example:

type Point = {
  x: number
  y: number
}

type Coordinate = keyof Point

const coord: Coordinate = 'x' // can also be 'y' but nothing else

Mapped types

A mapped type is a generic type which uses a union of PropertyKeys (frequently created via a keyof) to iterate through keys to create a type.

For example, suppose we want to create a type BoolPoint based on Point except where its x and y properties are booleans instead of numbers. We can create a generic mapped type ToBooleans to handle this:

type ToBooleans<T> = {
  [property in keyof T]: boolean
}

Now we can pass Point to ToBooleans to generate our desired BoolPoint type:

type BoolPoint = ToBooleans<Point>

const boolPoint: BoolPoint = {
  x: true,
  y: false,
}

Implementation

Define a generic type MyPick with two type parameters T and K where K extends keyof T so that K can only contain keys found in T (a generic constraint).

Inside the body of MyPick, P is declared as a key in K mapping the keys of K to the types of T using the syntax: [P in K]: T[P]

type MyPick<T, K extends keyof T> = {
  [P in K]: T[P]
}