John Jago

TypeScript has oddly specific types like Pick

The basics of TypeScript are easy if you know JavaScript. In JavaScript, each variable has a type. Because JavaScript is a dynamically typed language, there is no way to force a variable to be a certain type. A variable that holds a value of type number can be reassigned to a value of type string, and neither you nor the interpreter can do anything about it.

The eight data types are:

function is also a type because the typeof operator will respond with function when you write something like typeof function () {}. Since functions in JavaScript are first-class, meaning they can be passed around like values and assigned to variables, this makes sense.

It’s not surprising then that TypeScript allows you to declare variables as these data types.

const height: number = 3;
const spaceTowerHeight: bigint = 9007199254740991n;
const food: string = 'apple';
const pass: boolean = false;
const aNull: null = null;
const whyWouldYouWantThis: undefined = undefined;
const obj: object = { one: 1 };
const foodSymbol: symbol = Symbol(food);

It’s when you start diving deeper into the type system that you discover types you never knew existed.

Let’s take a look at one of these, the Pick<Type, Keys> type. It’s in the category of utility types, which are there to help you transform existing types. We’ll look at an example that makes use of some other features of TypeScript along the way.

First, let’s define a type called Hour which will allow one of the numbers that we specify. We can imagine that it’s for a day schedule, using the 12-hour clock.

type Hour = 8 | 9 | 10 | 11 | 12 | 1 | 2 | 3 | 4;

Now suppose we have a course with some information about it, including the start and end hour of the course. We model it like this:

interface Course {
    id: number,
    title: string,
    startTime: Hour,
    endTime: Hour,
}

In some views, we may not care about the id, which we can suppose is used for internal reference purposes. We can “pick” the properties that we want and create a new type out of the interface.

type CoursePreview = Pick<Course, 'title' | 'startTime' | 'endTime'>;

With these types, we can create one more interface and then an object that adheres to all the type requirements we’ve created.

interface Student {
    name: string,
    schedulePreview: Array<CoursePreview>,
}

const s: Student = {
    name: "Bob",
    schedulePreview: [{title: 'English 101', startTime: 2, endTime: 4}]
}

TypeScript has a comprehensive type system that even includes features like Pick which help you transform types.