Thuta Learning
ProjectsProgrammingintermediate

Mini Project: Task Manager - Part 1 (Setup & Structure)

Relax. We'll talk through this in plain words — no textbook voice.

What you'll walk away with

  • Apply Mini Project: Task Manager - Part 1 (Setup & Structure) in a real project
  • Write and run the code yourself
  • Build out an entire project step by step

Let's think about this for a second

In this project, we'll build a simple command-line Task Manager with TypeScript. In Part 1, the first thing we need to do is design the project's data shape. Since every task needs an id, title, status, priority, and so on, we'll define these with an interface, and constrain the possible values for status with an enum. Reusing basic types (string, number, boolean) alongside arrays and functions to lay down a solid foundation will make it much easier to add features later. Starting a project on a type-safe data structure is what keeps the resulting code light on bugs.

Let's build it

Create a Task interface with the fields id: number, title: string, status: TaskStatus, priority: "low" | "medium" | "high". Create an enum called TaskStatus with three members: Todo, InProgress, Done. Create an array tasks: Task[] = [] using the Task[] type, and implement two functions: addTask(task: Task): void and listTasks(): void. Inside listTasks(), loop over the tasks array and neatly print the title, status, and priority with console.log. Finally, add two sample tasks with addTask() and call listTasks() to check the result.

Sample code

typescript
enum TaskStatus {
  Todo = "TODO",
  InProgress = "IN_PROGRESS",
  Done = "DONE",
}

interface Task {
  id: number;
  title: string;
  status: TaskStatus;
  priority: "low" | "medium" | "high";
}

let tasks: Task[] = [];
let nextId = 1;

function addTask(title: string, priority: Task["priority"]): void {
  const task: Task = {
    id: nextId++,
    title,
    status: TaskStatus.Todo,
    priority,
  };
  tasks.push(task);
}

function listTasks(): void {
  tasks.forEach((t) => {
    console.log(`#${t.id} [${t.status}] ${t.title} (${t.priority})`);
  });
}

addTask("Learn TypeScript generics", "high");
addTask("Write project README", "low");

listTasks();
You should see
The console neatly prints the id, status, title, and priority of two tasks, one per line.

5-minute try it yourself

Add an optional field dueDate: string (as dueDate?: string) to the Task interface, and try adding a new task that includes a dueDate.

A quick word of caution

If you carefully structure your project's data shape with a well-defined interface from the start, you'll dramatically cut down the chance of bugs when adding new features in Part 2 and Part 3.

Easy traps

  • Relying on default numeric enum values instead of assigning string values to enum members, which makes log output hard to read
  • Typing the priority field as a plain string instead of a union type ("low" | "medium" | "high"), so the compiler can't catch a typo

Now try it yourself

Add an optional field dueDate: string (as dueDate?: string) to the Task interface, and try adding a new task that includes a dueDate.

You'll know it worked when: The console neatly prints the id, status, title, and priority of two tasks, one per line.