メインコンテンツにスキップ

End of the TypeScript Course

Summary and final challenge

Congratulations! You have completed all 5 modules of the TypeScript Course — from basic type annotations and primitive types to robust programming with Interfaces, Unions, highly versatile Generics, Classes/Utility Types, and Advanced Types/Guards. Below is a map of what you have mastered and a five-step final challenge.

Reminder: TypeScript exercises are verified statically (keywords). To actually run the code, each exercise provides a TypeScript Playground button that copies the code and opens typescriptlang.org/play.

01 · Fundamentals

  • annotations
  • primitive types
  • explicit vs implicit
  • arrays string[] / number[]
  • fixed tuples

02 · Types and Interfaces

  • interface
  • type alias
  • optional fields ?
  • union types |
  • type narrowing (typeof)

03 · Generics and Functions

  • typed functions
  • optional parameters
  • type signatures
  • generics <T>
  • generic classes and boxes

04 · Classes and Utility Types

  • classes and constructors
  • access modifiers (private/public)
  • interface implementation
  • utility types (Partial, Omit)
  • encapsulation best practices

05 · Advanced Types and Guards

  • type guards
  • is operator
  • typeof / instanceof
  • literal types
  • assertions as / as const
  • template literal types

The final challenge, in five steps

Combine what you have learned about TypeScript by building five small logical components: a generic array element retriever, an employee data helper with optional fields, an API response handler using discriminated unions, a task management system using classes/utility types, and a dashboard permission manager using custom type guards.

1 · First generic element

Write a generic function that accepts an array of elements of type T and returns the first element (or undefined if the array is empty). Module 3 (Generics).

運動#ts.boss.e1
試行回数: 0読み込み中…

Define the generic function firstElement<T>(arr: T[]): T | undefined that returns the first element of the array.

エディターを読み込み中…
ヒントを表示

Use the generic signature <T> before parameters. The function should return arr[0] or undefined.

3 回の試行後に解決策が利用可能になります

2 · Optional employee data helper

Define an Employee interface with an optional salary field, and a getSalary function that returns the salary or 0 if it is not specified. Module 2 (Interfaces and optional fields).

運動#ts.boss.e2
試行回数: 0読み込み中…

Create the Employee interface with id (number), name (string), and salary (optional number). Write getSalary(emp: Employee): number to check if salary is defined before returning it.

エディターを読み込み中…
ヒントを表示

Use the question mark salary?: number in the interface and the nullish coalescing operator (??) in the function.

3 回の試行後に解決策が利用可能になります

3 · Discriminated union for API response

Define a type to handle an API response that can be either a success (with generic data) or a failure (with a string message). Module 2 (Unions and Narrowing) + Module 3 (Generics).

運動#ts.boss.e3
試行回数: 0読み込み中…

Create ApiResponse<T> as a union of Success<T> (status: "success", data: T) and Failure (status: "error", message: string). Write handleResponse<T>(res: ApiResponse<T>): string that checks res.status and returns either "Data: " + res.data or "Error: " + res.message.

エディターを読み込み中…
ヒントを表示

Check res.status === "success" to narrow down the union type at runtime.

3 回の試行後に解決策が利用可能になります

4 · Task Manager Class

Define a NewTask type alias that omits id and completed from an existing Task interface, and implement a TaskManager class that manages a private array of Tasks. Module 4 (Classes and Utility Types).

運動#ts.boss.e4
試行回数: 0読み込み中…

Define the NewTask type by omitting id and completed from Task. Create the TaskManager class implementing ITaskManager, managing a private tasks array and a nextId counter starting from 1 to assign sequential IDs in the addTask method.

エディターを読み込み中…
ヒントを表示

Use type NewTask = Omit<Task, "id" | "completed">; to exclude the keys. In the class, define private tasks: Task[] = []; and private nextId: number = 1;.

3 回の試行後に解決策が利用可能になります

5 · Type guards and permissions

Define a NormalUser or Admin type with discriminated unions. Write a custom type guard isAdmin and a getDashboardAccess function to return a specific access string depending on the user role. Module 5 (Advanced Types and Guards).

運動#ts.boss.e5
試行回数: 0読み込み中…

Define the type guard isAdmin(user: User): user is Admin that checks if user.role === "admin". Then write the function getDashboardAccess(user: User): string that uses the isAdmin guard to return "Admin Access: " + user.permissions.join(", ") for admins, or "Standard Access for " + user.username for standard users.

エディターを読み込み中…
ヒントを表示

Use function isAdmin(user: User): user is Admin { return user.role === "admin"; }. In the getDashboardAccess function, use an if block to test isAdmin(user) before accessing the permissions property.

3 回の試行後に解決策が利用可能になります

Printable Cheatsheet

A single page with all the essential syntax of modern TypeScript, ready to keep handy while you code.

Open the cheatsheet

What now?

Consistent practice is the best way to strengthen your skills. Open the TypeScript Playground to experiment freely with complex scenarios or to prepare your code snippets before testing them in your actual projects.