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
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();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.