TypeScript 综合项目

把类型、类、泛型、模块、错误处理串起来,完成一个带类型安全的"任务管理 CLI"小项目,体会真实工程中 TS 如何分层协作。

需求与目录结构

实现添加任务、列出任务、完成任务三个功能,目录规划如下:

task-cli/
├─ package.json
├─ tsconfig.json
└─ src/
   ├─ types.ts      # 类型定义
   ├─ storage.ts    # 数据层:增删改查
   └─ main.ts       # 入口:业务与交互

第一步:定义领域类型 types.ts

用 interface 与字面量联合类型把"任务"和"状态"写清楚,拼写错误会在编译期暴露:

export type TaskStatus = "todo" | "done";
export interface Task {
  id: number;
  title: string;
  status: TaskStatus;
  createdAt: Date;
}

第二步:泛型仓储 storage.ts

用泛型封装内存数组,任何带 id 的对象都能复用同一套增删改查:

import type { Task } from "./types";
export class Store<T extends { id: number }> {
  private items: T[] = [];
  add(item: T): void { this.items.push(item); }
  find(id: number): T | undefined {
    return this.items.find((i) => i.id === id);
  }
  update(id: number, patch: Partial<T>): void { // Partial: 只更新部分字段
    const item = this.find(id);
    if (item) Object.assign(item, patch);
  }
  all(): readonly T[] { return this.items; }
}

第三步:业务逻辑与入口 main.ts

用 Store<Task> 组装业务,演示可选参数与按状态过滤:

import { Store } from "./storage";
import type { Task, TaskStatus } from "./types";
const store = new Store<Task>();
let nextId = 1;

function addTask(title: string): void {
  store.add({ id: nextId++, title, status: "todo", createdAt: new Date() });
}
function complete(id: number): void {
  store.update(id, { status: "done" });
}
function list(filter?: TaskStatus): void {
  store.all()
    .filter((t) => !filter || t.status === filter)
    .forEach((t) => console.log(`${t.id}. [${t.status}] ${t.title}`));
}

addTask("学习 TypeScript");
addTask("练习泛型");
complete(1);
list();        // 输出:1. [done] 学习 TypeScript / 2. [todo] 练习泛型
list("todo");  // 输出:2. [todo] 练习泛型

编译运行

安装 TypeScript 后编译并用 Node 运行:

npm i -D typescript
npx tsc --target ES2022 --module commonjs --outDir dist --strict
node dist/main.js

输出与上方注释一致。进阶方向:把 Store 改为读写 JSON 文件、加入自定义错误类型或单元测试。

小结

综合项目展示了典型分层:types.ts 定模型 → storage.ts 泛型抽象数据操作 → main.ts 组装业务,每一层的输入输出都有类型契约,重构与扩展更有底气。

笔记加载中…