Skip to main content

Easy Challenges

Easy challenges introduce fundamental TypeScript type operations. These challenges teach you essential patterns you’ll use throughout your TypeScript journey.
Total Challenges: 13 | Recommended for: Beginners to intermediate TypeScript developers

Challenge List

All 13 easy challenges, in recommended order:

#4 - Pick

Implement the built-in Pick utility type

#7 - Readonly

Make all properties readonly

#11 - Tuple to Object

Convert tuple to object type

#14 - First of Array

Get the first element type

#18 - Length of Tuple

Get tuple length as a type

#43 - Exclude

Implement the built-in Exclude type

#189 - Awaited

Unwrap Promise types

#268 - If

Implement conditional type branching

#533 - Concat

Concatenate two tuple types

#898 - Includes

Check if tuple includes a type

#3057 - Push

Add element to end of tuple

#3060 - Unshift

Add element to start of tuple

#3312 - Parameters

Get function parameter types

Description

Implement the built-in Pick<T, K> generic without using it. Constructs a type by picking the set of properties K from T.

Example

interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = MyPick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
  title: 'Clean room',
  completed: false,
}

Concepts

  • Mapped types
  • Key constraints
  • Index access types

Try this challenge

Open in TypeScript Playground

Description

Implement the built-in Readonly<T> generic without using it. Constructs a type with all properties of T set to readonly.

Example

interface Todo {
  title: string
  description: string
}

const todo: MyReadonly<Todo> = {
  title: "Hey",
  description: "foobar"
}

todo.title = "Hello" // Error: cannot reassign a readonly property

Concepts

  • Mapped types
  • Readonly modifier
  • Property iteration

Try this challenge

Open in TypeScript Playground

Description

Implement a type that unwraps Promise types. If we have a type which is wrapped type like Promise, how we can get the type which is inside?

Example

type ExampleType = Promise<string>
type Result = MyAwaited<ExampleType> // string

type Nested = Promise<Promise<number>>
type Result2 = MyAwaited<Nested> // number

Concepts

  • Conditional types
  • Type inference with infer
  • Recursive types

Try this challenge

Open in TypeScript Playground

Description

Implement a type If that accepts a condition C, a truthy return type T, and a falsy return type F. When C is true, return T, otherwise return F.

Example

type A = If<true, 'a', 'b'>  // expected to be 'a'
type B = If<false, 'a', 'b'> // expected to be 'b'

Concepts

  • Conditional types
  • Boolean type checking
  • Type branching

Try this challenge

Open in TypeScript Playground

Description

Implement a type Includes<T, U> that checks if type U is in the tuple type T.

Example

type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'> // false
type isJoJo = Includes<['Jonathan', 'Joseph', 'Jotaro'], 'Joseph'> // true

Concepts

  • Tuple iteration
  • Type equality checking
  • Recursive type processing

Try this challenge

Open in TypeScript Playground

Core Concepts

Easy challenges cover these fundamental patterns:

1. Mapped Types

Iterate over object keys and transform properties:
type Readonly<T> = {
  readonly [K in keyof T]: T[K]
}

2. Conditional Types

Create types based on conditions:
type If<C extends boolean, T, F> = C extends true ? T : F

3. Index Access

Access specific properties or elements:
type First<T extends any[]> = T[0]

4. Type Inference

Extract types using infer:
type Awaited<T> = T extends Promise<infer R> ? R : T

5. Tuple Manipulation

Work with fixed-length arrays:
type Push<T extends any[], U> = [...T, U]
type Unshift<T extends any[], U> = [U, ...T]

Learning Path

Recommended order for tackling easy challenges:
1

Object Utilities (4, 7)

Start with Pick and Readonly to learn mapped types
2

Tuple Basics (11, 14, 18)

Learn tuple type manipulation fundamentals
3

Conditionals (43, 268)

Master conditional types with Exclude and If
4

Advanced Patterns (189, 898)

Learn inference and recursion with Awaited and Includes
5

Tuple Operations (533, 3057, 3060, 3312)

Complete your tuple manipulation skills

Tips for Easy Challenges

Many challenges use mapped types. Understanding [K in keyof T] is essential. Practice with Pick and Readonly before moving on.
extends is used for both constraints and conditionals. Understanding the difference is crucial:
// Constraint: T must be an array
type First<T extends any[]> = ...

// Conditional: check if T is an array
type IsArray<T> = T extends any[] ? true : false
Several challenges work with tuples. Remember that tuples are arrays with known lengths:
type Tuple = [string, number, boolean]
type Arr = string[] // not a tuple
When you need to extract a type, use infer:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never
Always check your solution against all test cases. Sometimes a solution works for simple cases but fails on edge cases.

Common Patterns You’ll Use

Pattern 1: Property Selection

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

Pattern 2: Property Modification

type Readonly<T> = {
  readonly [K in keyof T]: T[K]
}

Pattern 3: Array Element Access

type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never

Pattern 4: Type Filtering

type Exclude<T, U> = T extends U ? never : T

Next Steps

After completing easy challenges, you’re ready for:

Medium Challenges

104 challenges to build intermediate skills

TypeScript Handbook

Deep dive into mapped types