CC
0 XP
0

Chapter 2: Build Core Todo

Data Model

concept5 min

Data Model

Every app starts with its data. Let's use Claude Code to think through and create the TypeScript types that will define what a "todo" looks like in our application.

Thinking through the shape

Start by asking Claude Code to help design the type:

"I need a TypeScript type for a Todo item. It should support: a unique ID, title text, completed status, creation date, and later we'll add category, priority, and due date. Create the type in src/types/todo.ts. Start simple -- we'll extend it as we add features."

💡Info

Notice the prompt says "start simple -- we'll extend it." This is a key habit. Tell Claude Code your future plans so it designs for extension, but only builds what you need now.

What Claude Code creates

Claude Code will generate a file at src/types/todo.ts:

export interface Todo {
  id: string;
  title: string;
  completed: boolean;
  createdAt: string;
}
Tip

Claude Code uses string for the id instead of number. This is intentional -- string IDs (like UUIDs) are safer for client-side apps where there's no database generating auto-increment IDs. Ask Claude Code why if you're curious!

Why an interface and not a type?

You might wonder why Claude Code picked interface over type. Ask it:

"Why did you use interface instead of type for Todo? When should I use each?"

Claude Code will explain that interface is extensible (you can add fields later with declaration merging) and is the TypeScript convention for object shapes. type is better for unions, intersections, and computed types. For our use case, interface is the right call.

Add sample data

We need some todos to display before we build the add form. Ask Claude Code:

"Create a sample data file at src/data/sample-todos.ts with 3-4 example todos using the Todo type. Include a mix of completed and incomplete items."

Claude Code will create something like:

import { Todo } from '@/types/todo';
 
export const sampleTodos: Todo[] = [
  {
    id: '1',
    title: 'Learn Claude Code',
    completed: true,
    createdAt: new Date().toISOString(),
  },
  {
    id: '2',
    title: 'Build a todo app',
    completed: false,
    createdAt: new Date().toISOString(),
  },
  {
    id: '3',
    title: 'Add categories and priorities',
    completed: false,
    createdAt: new Date().toISOString(),
  },
];
Tip

Creating sample data isn't just for testing — it's a form of few-shot prompting. By showing Claude what your data looks like, it generates consistent patterns throughout the app. Every component Claude builds will match this data shape because it has a concrete example to follow.

A helper for generating IDs

Ask Claude Code to add an ID utility:

"Add a generateId function in the same types file or a utils file. Use crypto.randomUUID() for generating unique IDs."

export function generateId(): string {
  return crypto.randomUUID();
}
⚠️Warning

crypto.randomUUID() works in all modern browsers and Node 19+. If you need to support older environments, Claude Code can suggest alternatives like the uuid package.

The data model pattern

Notice what we did here: we asked Claude Code to design the type, then questioned its choices, then added supporting data. This design-question-extend loop is incredibly productive.

The types file is small now, but it's the backbone of the entire app. Every component we build will import and use the Todo interface.