AzLearn

تمرين إعادة البناء

Todo List JSON

أعد كتابة قائمة مهام TypeScript تخزن بياناتها كـ JSON.

typescript ~16 دقيقة مبتدئ
أعد بناء الكود Rebuild

هذا هو الكود. اكتبه بنفسك.

الكود المرجعي
// Run with: npx tsx 07-todo-list-json.ts [task text] (requires @types/node).
import * as fs from "node:fs";

type TodoStatus = "open" | "done";

interface TodoItem {
  id: number;
  text: string;
  status: TodoStatus;
}

const filePath = "todos.json";

function isTodoItem(value: unknown): value is TodoItem {
  if (typeof value !== "object" || value === null) {
    return false;
  }
  const candidate = value as Record<string, unknown>;
  return (
    typeof candidate.id === "number" &&
    typeof candidate.text === "string" &&
    (candidate.status === "open" || candidate.status === "done")
  );
}

function loadTodos(): TodoItem[] {
  if (!fs.existsSync(filePath)) {
    return [];
  }

  const raw = fs.readFileSync(filePath, "utf8");
  const parsed: unknown = JSON.parse(raw);

  if (!Array.isArray(parsed) || !parsed.every(isTodoItem)) {
    throw new Error("invalid todos.json");
  }

  return parsed;
}

function saveTodos(todos: TodoItem[]): void {
  fs.writeFileSync(filePath, JSON.stringify(todos, null, 2));
}

function addTodo(text: string): TodoItem {
  const todos = loadTodos();
  const nextId = todos.length === 0 ? 1 : Math.max(...todos.map((todo) => todo.id)) + 1;
  const todo: TodoItem = { id: nextId, text, status: "open" };

  saveTodos([...todos, todo]);
  return todo;
}

const text = process.argv.slice(2).join(" ") || "Practice TypeScript";
const todo = addTodo(text);
console.log(`Added #${todo.id}: ${todo.text}`);
اكتب هنا