Skip to content

Type Gymnastic - Part 1

Posted on:August 29, 2023 at 03:00 PM

Typescript’s type system can be very powerfull once you get to know all of its mysterious ways of juggling it. Let’s dive deep into some of its features.

Table of contents

Open Table of contents

Intro

A while ago I created an advent calender for fun with one typescript challenge each day. You can check it out here. Give it a go if you feel comfortable with Typescript! This post will go through every challenge with some explanation and helpfull links if you want to read more about it. If you are totally new to Typescript I would recommend reading through the handbook.

Warm up

The first challenges of the aforementioned advent calender would be considered a warm up for typescript gymnasts.

Challenge 1

You are given the type

type Hello = any;

edit the type such that it only allows the value “Hello Santa”. To solve this, you can simply set the type to that exact string value:

type Hello = "Hello Santa";

If you now use this type for a variable, you are not allowed to set the value of the variable to be anything other than “Hello Santa”:

let test: Hello = "Hello Santa";

test = "Hello World"; // Type error!!!

Challenge 2

You are given the type:

type SecondOfArray<T> = any;

and you want to edit it so the type is equal to second element of an array that is passed as a generic T. If the generic is not an array or has no second element, consider it as undefined.

To solve this we want to use conditional types (similar to conditional expressions in JavaScript) to figure out if the generic T is an array or not.

type SecondOfArray<T> = T extends Array<any> ? any : undefined;

So far so good, we check if T is an array, and if that’s true we will set the SecondOfArray type to be any if not it will be undefined.

Now to be able to retrieve the second element of T we can use index accessing on T:

type SecondOfArray<T> = T extends Array<any> ? T[1] : undefined;

And if you use this type:

type Test = SecondOfArray<[1, 2, 3]>; // Test = 2
type Test2 = SecondOfArray<[1]>; // Test2 = undefined

Challenge 3

You are given the type:

type LengthOfStringArray<T> = any;

edit the type such that you are able to find the length of a given string array that is passed as a generic T.

So a couple of things we need to pay attention to here:

We can use our knowledge from challenge #2 about generics, but instead of allowing the generic T to be anything we now want to add a type constraint:

type LengthOfStringArray<T extends Array<string>> = any;

This constraint will only allow string array to be passed as a generic to the type. Because of this, we already know that T will contain specific properties related to arrays - such as the length property!

type LengthOfStringArray<T extends Array<string>> = T["length"];

And when you use the type:

type Test = LengthOfStringArray<[]>; // Test = 0
type Test2 = LengthOfStringArray<["One", "Two"]>; // Test = 2

type Test3 = LengthOfStringArray<"This is not an array :)">; // Will cause a type error because of the constraint!

That’s enough warmup for now - part 2 coming soon! part 2 is here

Relevant reading