当前位置:首页 > 文章列表 > 文章 > 前端 > TypeScript 综合项目实战

TypeScript 综合项目实战

2026-08-21 03:10:32 0浏览 收藏

这篇教程不会只停留在零散知识点上,而是借助一个完整的项目案例,把 TypeScript 的各种特性系统地串联起来、用起来。

TypeScript 综合项目实战

从项目搭建一路讲到真实开发场景,把 TypeScript 在实际项目里到底怎么用,完整地呈现出来。

项目实战:任务管理系统前端 (React + TS)Vite + React 18组件 + Hooks类型安全的 UI后端 (Node.js)Express + TSRESTful API类型定义数据存储In-Memory(演示)项目功能特性任务 CRUD 操作类型安全的 API状态管理

为什么需要综合项目实战

学习 TypeScript 语法后,需要通过实际项目来巩固知识。

本教程展示一个完整的任务管理系统,涵盖前端、后端和类型定义。

通过这个项目,可以掌握 TypeScript 在实际开发中的最佳实践。

项目目标:创建任务管理系统,包含任务创建、查询、更新、删除功能。

项目结构

使用 Monorepo 风格组织项目结构。

目录结构

task-manager/
├── src/
│   ├── types/                 # 类型定义
│   │   ├── task.ts           # 任务类型
│   │   ├── api.ts            # API 类型
│   │   └── index.ts          # 类型导出
│   │
│   ├── services/             # 服务层
│   │   ├── taskService.ts   # 任务服务
│   │   └── index.ts
│   │
│   ├── components/           # React 组件
│   │   ├── TaskList.tsx     # 任务列表
│   │   ├── TaskItem.tsx     # 任务项
│   │   ├── TaskForm.tsx     # 任务表单
│   │   └── index.ts
│   │
│   ├── hooks/                # 自定义 Hooks
│   │   ├── useTasks.ts      # 任务状态管理
│   │   └── index.ts
│   │
│   ├── App.tsx               # 主应用
│   ├── App.css               # 样式
│   └── main.tsx              # 入口文件
│
├── index.html
├── package.json
├── tsconfig.json
└── vite.config.ts

目录划分:按功能划分目录,类型定义、服务层、组件分离。

类型定义

首先定义项目的核心类型。

src/types/task.ts

// 任务状态枚举
export type TaskStatus = "pending" | "in-progress" | "completed";
// 任务优先级枚举
export type TaskPriority = "low" | "medium" | "high";
// 任务接口定义
export interface Task {
    id: string;               // 任务ID
    title: string;            // 任务标题
    description?: string;      // 任务描述(可选)
    status: TaskStatus;       // 任务状态
    priority: TaskPriority;   // 任务优先级
    createdAt: string;        // 创建时间
    updatedAt: string;         // 更新时间
    dueDate?: string;         // 截止日期(可选)
    tags?: string[];          // 标签(可选)
}
// 创建任务的输入类型
export interface CreateTaskInput {
    title: string;
    description?: string;
    priority: TaskPriority;
    dueDate?: string;
    tags?: string[];
}
// 更新任务的输入类型
export interface UpdateTaskInput {
    title?: string;
    description?: string;
    status?: TaskStatus;
    priority?: TaskPriority;
    dueDate?: string;
    tags?: string[];
}
// 任务过滤选项
export interface TaskFilter {
    status?: TaskStatus;
    priority?: TaskPriority;
    search?: string;
}

类型分层:将输入类型、输出类型、过滤类型分开定义,便于维护。

API 类型定义

定义 API 相关的类型。

src/types/api.ts
// 通用 API 响应类型
export interface ApiResponse {
    success: boolean;
    data?: T;
    error?: string;
    message?: string;
}
// 分页元数据
export interface PaginationMeta {
    total: number;
    page: number;
    pageSize: number;
    totalPages: number;
}
// 分页响应类型
export interface PaginatedResponse {
    items: T[];
    meta: PaginationMeta;
}
// 请求错误类型
export interface ApiError {
    code: string;
    message: string;
    details?: Record;
}
// HTTP 方法类型
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
// 任务相关的 API 端点
export interface TaskEndpoints {
    getAll: "/api/tasks";
    getById: "/api/tasks/:id";
    create: "/api/tasks";
    update: "/api/tasks/:id";
    delete: "/api/tasks/:id";
}

API 类型:统一的响应格式和错误处理类型,便于前后端对接。

任务服务层

实现任务管理的业务逻辑。

src/services/taskService.ts

// 导入类型定义
import {
    Task,
    CreateTaskInput,
    UpdateTaskInput,
    TaskFilter,
    TaskStatus,
    TaskPriority
} from "../types/task";
// 生成唯一ID
function generateId(): string {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
// 模拟数据库(内存存储)
let tasks: Task[] = [
    {
        id: "1",
        title: "学习 TypeScript",
        description: "掌握 TypeScript 基础和高级特性",
        status: "completed",
        priority: "high",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
        tags: ["学习", "TypeScript"]
    },
    {
        id: "2",
        title: "开发任务管理系统",
        description: "使用 React + TypeScript 开发",
        status: "in-progress",
        priority: "high",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
        tags: ["项目", "实战"]
    }
];
// 任务服务类
class TaskService {
    // 获取所有任务
    getAll(filter?: TaskFilter): Task[] {
        let result = [...tasks];
        if (filter) {
            if (filter.status) {
                result = result.filter(t => t.status === filter.status);
            }
            if (filter.priority) {
                result = result.filter(t => t.priority === filter.priority);
            }
            if (filter.search) {
                const search = filter.search.toLowerCase();
                result = result.filter(t =>
                    t.title.toLowerCase().includes(search) ||
                    t.description?.toLowerCase().includes(search)
                );
            }
        }
        return result;
    }
    // 根据ID获取任务
    getById(id: string): Task | undefined {
        return tasks.find(t => t.id === id);
    }
    // 创建任务
    create(input: CreateTaskInput): Task {
        const now = new Date().toISOString();
        const task: Task = {
            id: generateId(),
            title: input.title,
            description: input.description,
            status: "pending",
            priority: input.priority,
            createdAt: now,
            updatedAt: now,
            dueDate: input.dueDate,
            tags: input.tags
        };
        tasks.push(task);
        return task;
    }
    // 更新任务
    update(id: string, input: UpdateTaskInput): Task | null {
        const index = tasks.findIndex(t => t.id === id);
        if (index === -1) return null;
        const task = tasks[index];
        const updated: Task = {
            ...task,
            ...input,
            updatedAt: new Date().toISOString()
        };
        tasks[index] = updated;
        return updated;
    }
    // 删除任务
    delete(id: string): boolean {
        const index = tasks.findIndex(t => t.id === id);
        if (index === -1) return false;
        tasks.splice(index, 1);
        return true;
    }
    // 更新任务状态
    updateStatus(id: string, status: TaskStatus): Task | null {
        return this.update(id, { status });
    }
}
// 导出服务实例
export const taskService = new TaskService();

服务层:业务逻辑集中在服务层,便于测试和维护。

自定义 Hook

使用 Hook 管理任务状态。

src/hooks/useTasks.ts
// 导入 React Hooks 和类型
import { useState, useEffect, useCallback } from "react";
import {
    Task,
    CreateTaskInput,
    UpdateTaskInput,
    TaskFilter,
    TaskStatus,
    TaskPriority
} from "../types/task";
import { taskService } from "../services/taskService";
// Hook 返回的状态类型
interface UseTasksReturn {
    tasks: Task[];
    loading: boolean;
    error: string | null;
    filter: TaskFilter;
    // 操作方法
    createTask: (input: CreateTaskInput) => Promise;
    updateTask: (id: string, input: UpdateTaskInput) => Promise;
    deleteTask: (id: string) => Promise;
    updateStatus: (id: string, status: TaskStatus) => Promise;
    setFilter: (filter: TaskFilter) => void;
    refresh: () => void;
}
// 初始化默认过滤器
const defaultFilter: TaskFilter = {};
export function useTasks(): UseTasksReturn {
    // 任务列表状态
    const [tasks, setTasks] = useState([]);
    // 加载状态
    const [loading, setLoading] = useState(true);
    // 错误状态
    const [error, setError] = useState(null);
    // 过滤条件
    const [filter, setFilter] = useState(defaultFilter);
    // 加载任务列表
    const loadTasks = useCallback(() => {
        setLoading(true);
        setError(null);
        try {
            const data = taskService.getAll(filter);
            setTasks(data);
        } catch (err) {
            setError(err instanceof Error ? err.message : "加载失败");
        } finally {
            setLoading(false);
        }
    }, [filter]);
    // 初始加载和过滤器变化时重新加载
    useEffect(() => {
        loadTasks();
    }, [loadTasks]);
    // 创建任务
    const createTask = useCallback(async (input: CreateTaskInput) => {
        try {
            taskService.create(input);
            loadTasks();
        } catch (err) {
            setError(err instanceof Error ? err.message : "创建失败");
        }
    }, [loadTasks]);
    // 更新任务
    const updateTask = useCallback(async (id: string, input: UpdateTaskInput) => {
        try {
            taskService.update(id, input);
            loadTasks();
        } catch (err) {
            setError(err instanceof Error ? err.message : "更新失败");
        }
    }, [loadTasks]);
    // 删除任务
    const deleteTask = useCallback(async (id: string) => {
        try {
            taskService.delete(id);
            loadTasks();
        } catch (err) {
            setError(err instanceof Error ? err.message : "删除失败");
        }
    }, [loadTasks]);
    // 更新任务状态
    const updateStatus = useCallback(async (id: string, status: TaskStatus) => {
        try {
            taskService.updateStatus(id, status);
            loadTasks();
        } catch (err) {
            setError(err instanceof Error ? err.message : "状态更新失败");
        }
    }, [loadTasks]);
    // 刷新任务列表
    const refresh = useCallback(() => {
        loadTasks();
    }, [loadTasks]);
    return {
        tasks,
        loading,
        error,
        filter,
        createTask,
        updateTask,
        deleteTask,
        updateStatus,
        setFilter,
        refresh
    };
}

自定义 Hook:将状态管理和业务逻辑封装在 Hook 中,组件更简洁。

React 组件

使用 Hook 创建任务列表组件。

src/components/TaskList.tsx

// 导入 React 和自定义 Hook
import React from "react";
import { useTasks } from "../hooks/useTasks";
import { Task, TaskStatus, TaskPriority } from "../types/task";
// 任务项组件 Props
interface TaskItemProps {
    task: Task;
    onStatusChange: (id: string, status: TaskStatus) => void;
    onDelete: (id: string) => void;
}
// 任务项组件
const TaskItem: React.FC = ({
    task,
    onStatusChange,
    onDelete
}) => {
    // 状态样式映射
    const statusStyles: Record = {
        "pending": "status-pending",
        "in-progress": "status-progress",
        "completed": "status-completed"
    };
    // 优先级样式映射
    const priorityLabels: Record = {
        "low": "低",
        "medium": "中",
        "high": "高"
    };
    return (
        

{task.title}

{task.description && (

{task.description}

)}
{priorityLabels[task.priority]} {new Date(task.createdAt).toLocaleDateString()}
); }; // 任务列表组件 export const TaskList: React.FC = () => { // 使用自定义 Hook 获取任务状态 const { tasks, loading, error, updateStatus, deleteTask } = useTasks(); // 渲染加载状态 if (loading) { return
加载中...
; } // 渲染错误状态 if (error) { return
错误: {error}
; } // 渲染空状态 if (tasks.length === 0) { return (

暂无任务

点击上方按钮创建新任务

); } // 渲染任务列表 return (
{tasks.map(task => ( ))}
); }; export default TaskList;

组件拆分:将 TaskItem 拆分为独立组件,代码更清晰。

主应用组件

整合所有组件,组成完整的应用。

src/App.tsx

// 导入 React 和类型
import React, { useState } from "react";
import { TaskList } from "./components/TaskList";
import { useTasks } from "./hooks/useTasks";
import { CreateTaskInput, TaskPriority } from "./types/task";
import "./App.css";
// 任务表单组件 Props
interface TaskFormProps {
    onSubmit: (input: CreateTaskInput) => void;
}
// 任务表单组件
const TaskForm: React.FC = ({ onSubmit }) => {
    // 表单状态
    const [title, setTitle] = useState("");
    const [description, setDescription] = useState("");
    const [priority, setPriority] = useState("medium");
    // 提交处理
    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        if (!title.trim()) {
            alert("请输入任务标题");
            return;
        }
        onSubmit({
            title: title.trim(),
            description: description.trim() || undefined,
            priority
        });
        // 重置表单
        setTitle("");
        setDescription("");
        setPriority("medium");
    };
    return (
        
setTitle(e.target.value)} placeholder="输入任务标题" className="form-input" /> setDescription(e.target.value)} placeholder="输入任务描述(可选)" className="form-input" />
); }; // 主应用组件 const App: React.FC = () => { // 使用自定义 Hook const { createTask, error } = useTasks(); // 渲染错误提示 const renderError = () => { if (!error) return null; return
{error}
; }; return (

TypeScript 任务管理系统

综合实战项目

{renderError()}

Powered by TypeScript + React

); }; export default App;

组件组合:通过组合简单的组件构建复杂的 UI。

项目配置

项目的 TypeScript 和构建配置。

tsconfig.json

{
    "compilerOptions": {
        "target": "ES2020",
        "useDefineForClassFields": true,
        "lib": ["ES2020", "DOM", "DOM.Iterable"],
        "module": "ESNext",
        "skipLibCheck": true,
        "moduleResolution": "bundler",
        "allowImportingTsExtensions": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react-jsx",
        "strict": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "noFallthroughCasesInSwitch": true
    },
    "include": ["src"],
    "references": [{ "path": "./tsconfig.node.json" }]
}

严格模式:启用 strict 获得最完整的类型检查。

注意事项

  • 类型优先:先定义类型,再编写实现代码
  • 接口 vs 类型:对象类型用接口,联合类型用类型别名
  • 分层架构:类型、服务、组件分层组织
  • Hook 封装:业务逻辑封装在 Hook 中

最佳实践:类型定义是 TypeScript 项目的基础,要认真设计。

总结

通过这个综合项目,我们实践了 TypeScript 的核心概念。

  • 类型定义:Task、CreateTaskInput、TaskFilter 等接口
  • 服务层:TaskService 封装业务逻辑
  • 自定义 Hook:useTasks 管理状态
  • React 组件:类型安全的组件开发
  • 项目配置:严格的 TypeScript 配置

建议:多参与实际项目,在实践中加深对 TypeScript 的理解。

TypeScript + Vue3 实战TypeScript + Vue3 实战
上一篇
TypeScript + Vue3 实战
Java record compact constructor 怎么校验时间区间:跨字段不变量与异常契约
下一篇
Java record compact constructor 怎么校验时间区间:跨字段不变量与异常契约
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ljg-skills -
    ljg-skills
    ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
    5043次使用
  • MELO音乐 - AI 音乐生成平台,支持多模态创作能力
    MELO音乐
    MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
    4575次使用
  • UniScribe - AI 免费在线音视频转文字平台
    UniScribe
    UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
    4528次使用
  • 剧云 - 免费 AI 智能中文剧本创作平台
    剧云
    剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
    4781次使用
  • 万象有声 - AI 一站式有声内容创作平台
    万象有声
    万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
    4733次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码