Skip to main content

Todo List Project Introduction

Learning syntax in isolation only goes so far. It's time to build something end-to-end to see how the type system interacts with the DOM.

The Goal

We are going to build a vanilla HTML/CSS/TypeScript Todo application. No React, no frameworks, just pure TypeScript orchestrating the DOM.

Features:

  1. Render a list of todos from an array of data.
  2. Add a new todo via an HTML form.
  3. Toggle a todo's completion status via a checkbox.
  4. Save and load the state from the browser's localStorage.

Why this project?

This project seems simple, but it forces you to confront the three most common sharp edges in client-side TypeScript:

  1. Typing DOM Elements: TypeScript doesn't know what HTML is in your index.html. You have to safely select and cast elements (e.g., proving an element is an HTMLInputElement and not just a generic HTMLElement).
  2. Typing Events: Handling form submissions and click events requires precise typing so you can access properties like e.preventDefault() or e.target.checked without compiler errors.
  3. Typing External Data: localStorage.getItem() returns a string or null. JSON.parse() returns any. You must safely validate and parse this untyped data back into a strict array of Todo objects.

Setup Instructions

We'll use Vite to rapidly scaffold the project so we don't have to configure Webpack or TS compilers manually.

Run this in your terminal:

npm create vite@latest ts-todo -- --template vanilla-ts
cd ts-todo
npm install
npm run dev

Building a Vanilla TS app forces you to learn how to bridge the gap between TypeScript's strict compile-time guarantees and the inherently untyped nature of the browser DOM.