Skip to content

TypeScript 实战综合案例

本章节将通过几个综合案例,展示 TypeScript 在实际项目中的应用,帮助你理解如何在真实场景中使用 TypeScript。

接口定义接口数据结构

示例:定义 API 接口数据结构

typescript
// 定义用户接口
interface User {
  id: number;
  name: string;
  email: string;
  age?: number;
  address?: {
    street: string;
    city: string;
    country: string;
  };
  createdAt: string;
  updatedAt: string;
}

// 定义产品接口
interface Product {
  id: number;
  name: string;
  price: number;
  description: string;
  category: string;
  stock: number;
  imageUrl: string;
  createdAt: string;
  updatedAt: string;
}

// 定义订单接口
interface Order {
  id: number;
  userId: number;
  user?: User;
  items: OrderItem[];
  total: number;
  status: "pending" | "processing" | "shipped" | "delivered" | "cancelled";
  createdAt: string;
  updatedAt: string;
}

// 定义订单项接口
interface OrderItem {
  id: number;
  orderId: number;
  productId: number;
  product?: Product;
  quantity: number;
  price: number;
}

// 定义 API 响应接口
interface ApiResponse<T> {
  success: boolean;
  data?: T;
  error?: {
    code: number;
    message: string;
  };
  pagination?: {
    page: number;
    pageSize: number;
    total: number;
  };
}

// 使用示例
async function fetchUsers(): Promise<ApiResponse<User[]>> {
  const response = await fetch('/api/users');
  return response.json();
}

async function fetchProducts(): Promise<ApiResponse<Product[]>> {
  const response = await fetch('/api/products');
  return response.json();
}

async function fetchOrders(): Promise<ApiResponse<Order[]>> {
  const response = await fetch('/api/orders');
  return response.json();
}

函数封装 + 泛型工具

示例:封装通用 API 客户端

typescript
// 定义 API 客户端
class ApiClient {
  private baseUrl: string;

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl;
  }

  // 通用 GET 请求
  async get<T>(endpoint: string, params?: Record<string, any>): Promise<ApiResponse<T>> {
    const url = new URL(`${this.baseUrl}${endpoint}`);
    
    if (params) {
      Object.entries(params).forEach(([key, value]) => {
        url.searchParams.append(key, value.toString());
      });
    }

    const response = await fetch(url.toString());
    return response.json();
  }

  // 通用 POST 请求
  async post<T>(endpoint: string, data: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });
    return response.json();
  }

  // 通用 PUT 请求
  async put<T>(endpoint: string, data: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });
    return response.json();
  }

  // 通用 DELETE 请求
  async delete<T>(endpoint: string): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'DELETE',
    });
    return response.json();
  }
}

// 使用示例
const apiClient = new ApiClient('https://api.example.com');

// 获取用户列表
async function getUsers() {
  const response = await apiClient.get<User[]>('/users', {
    page: 1,
    pageSize: 10,
  });
  
  if (response.success && response.data) {
    console.log(response.data);
  }
}

// 创建用户
async function createUser(user: Omit<User, 'id' | 'createdAt' | 'updatedAt'>) {
  const response = await apiClient.post<User>('/users', user);
  
  if (response.success && response.data) {
    console.log('User created:', response.data);
  }
}

// 更新用户
async function updateUser(id: number, user: Partial<User>) {
  const response = await apiClient.put<User>(`/users/${id}`, user);
  
  if (response.success && response.data) {
    console.log('User updated:', response.data);
  }
}

// 删除用户
async function deleteUser(id: number) {
  const response = await apiClient.delete<{ message: string }>(`/users/${id}`);
  
  if (response.success) {
    console.log(response.data?.message);
  }
}

类封装业务逻辑

示例:用户管理服务

typescript
// 用户服务
class UserService {
  private apiClient: ApiClient;

  constructor(apiClient: ApiClient) {
    this.apiClient = apiClient;
  }

  // 获取用户列表
  async getUsers(page: number = 1, pageSize: number = 10): Promise<User[]> {
    const response = await this.apiClient.get<User[]>('/users', {
      page,
      pageSize,
    });

    if (!response.success || !response.data) {
      throw new Error(response.error?.message || 'Failed to get users');
    }

    return response.data;
  }

  // 获取单个用户
  async getUser(id: number): Promise<User> {
    const response = await this.apiClient.get<User>(`/users/${id}`);

    if (!response.success || !response.data) {
      throw new Error(response.error?.message || 'Failed to get user');
    }

    return response.data;
  }

  // 创建用户
  async createUser(userData: Omit<User, 'id' | 'createdAt' | 'updatedAt'>): Promise<User> {
    const response = await this.apiClient.post<User>('/users', userData);

    if (!response.success || !response.data) {
      throw new Error(response.error?.message || 'Failed to create user');
    }

    return response.data;
  }

  // 更新用户
  async updateUser(id: number, userData: Partial<User>): Promise<User> {
    const response = await this.apiClient.put<User>(`/users/${id}`, userData);

    if (!response.success || !response.data) {
      throw new Error(response.error?.message || 'Failed to update user');
    }

    return response.data;
  }

  // 删除用户
  async deleteUser(id: number): Promise<void> {
    const response = await this.apiClient.delete<{ message: string }>(`/users/${id}`);

    if (!response.success) {
      throw new Error(response.error?.message || 'Failed to delete user');
    }
  }

  // 搜索用户
  async searchUsers(query: string): Promise<User[]> {
    const response = await this.apiClient.get<User[]>('/users/search', {
      q: query,
    });

    if (!response.success || !response.data) {
      throw new Error(response.error?.message || 'Failed to search users');
    }

    return response.data;
  }
}

// 使用示例
const apiClient = new ApiClient('https://api.example.com');
const userService = new UserService(apiClient);

// 获取用户列表
userService.getUsers(1, 20)
  .then(users => console.log(users))
  .catch(error => console.error(error));

// 创建用户
userService.createUser({
  name: 'John Doe',
  email: 'john@example.com',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'New York',
    country: 'USA',
  },
})
  .then(user => console.log('Created user:', user))
  .catch(error => console.error(error));

类型约束表单数据

示例:表单验证

typescript
// 定义表单类型
interface LoginForm {
  email: string;
  password: string;
  rememberMe?: boolean;
}

interface RegisterForm {
  name: string;
  email: string;
  password: string;
  confirmPassword: string;
  agreeToTerms: boolean;
}

// 表单验证服务
class FormValidator {
  // 验证登录表单
  static validateLoginForm(form: LoginForm): Partial<Record<keyof LoginForm, string>> {
    const errors: Partial<Record<keyof LoginForm, string>> = {};

    if (!form.email) {
      errors.email = 'Email is required';
    } else if (!this.isValidEmail(form.email)) {
      errors.email = 'Invalid email address';
    }

    if (!form.password) {
      errors.password = 'Password is required';
    } else if (form.password.length < 8) {
      errors.password = 'Password must be at least 8 characters';
    }

    return errors;
  }

  // 验证注册表单
  static validateRegisterForm(form: RegisterForm): Partial<Record<keyof RegisterForm, string>> {
    const errors: Partial<Record<keyof RegisterForm, string>> = {};

    if (!form.name) {
      errors.name = 'Name is required';
    }

    if (!form.email) {
      errors.email = 'Email is required';
    } else if (!this.isValidEmail(form.email)) {
      errors.email = 'Invalid email address';
    }

    if (!form.password) {
      errors.password = 'Password is required';
    } else if (form.password.length < 8) {
      errors.password = 'Password must be at least 8 characters';
    }

    if (!form.confirmPassword) {
      errors.confirmPassword = 'Please confirm your password';
    } else if (form.confirmPassword !== form.password) {
      errors.confirmPassword = 'Passwords do not match';
    }

    if (!form.agreeToTerms) {
      errors.agreeToTerms = 'You must agree to the terms and conditions';
    }

    return errors;
  }

  // 验证邮箱格式
  private static isValidEmail(email: string): boolean {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
  }
}

// 使用示例
const loginForm: LoginForm = {
  email: 'john@example.com',
  password: 'password123',
  rememberMe: true,
};

const loginErrors = FormValidator.validateLoginForm(loginForm);
if (Object.keys(loginErrors).length === 0) {
  console.log('Login form is valid');
} else {
  console.log('Login form errors:', loginErrors);
}

const registerForm: RegisterForm = {
  name: 'John Doe',
  email: 'john@example.com',
  password: 'password123',
  confirmPassword: 'password123',
  agreeToTerms: true,
};

const registerErrors = FormValidator.validateRegisterForm(registerForm);
if (Object.keys(registerErrors).length === 0) {
  console.log('Register form is valid');
} else {
  console.log('Register form errors:', registerErrors);
}

TS 写一个 TodoList

示例:TodoList 应用

typescript
// 定义 Todo 类型
export interface Todo {
  id: number;
  title: string;
  description?: string;
  completed: boolean;
  createdAt: string;
  updatedAt: string;
}

// 定义 Todo 服务
class TodoService {
  private todos: Todo[] = [];
  private nextId = 1;

  // 获取所有 Todo
  getTodos(): Todo[] {
    return this.todos;
  }

  // 获取单个 Todo
  getTodo(id: number): Todo | undefined {
    return this.todos.find(todo => todo.id === id);
  }

  // 创建 Todo
  createTodo(todo: Omit<Todo, 'id' | 'completed' | 'createdAt' | 'updatedAt'>): Todo {
    const newTodo: Todo = {
      ...todo,
      id: this.nextId++,
      completed: false,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };

    this.todos.push(newTodo);
    return newTodo;
  }

  // 更新 Todo
  updateTodo(id: number, updates: Partial<Omit<Todo, 'id' | 'createdAt' | 'updatedAt'>>): Todo | undefined {
    const index = this.todos.findIndex(todo => todo.id === id);
    
    if (index === -1) {
      return undefined;
    }

    const updatedTodo: Todo = {
      ...this.todos[index],
      ...updates,
      updatedAt: new Date().toISOString(),
    };

    this.todos[index] = updatedTodo;
    return updatedTodo;
  }

  // 删除 Todo
  deleteTodo(id: number): boolean {
    const index = this.todos.findIndex(todo => todo.id === id);
    
    if (index === -1) {
      return false;
    }

    this.todos.splice(index, 1);
    return true;
  }

  // 切换 Todo 完成状态
  toggleTodo(id: number): Todo | undefined {
    return this.updateTodo(id, {
      completed: !this.todos.find(todo => todo.id === id)?.completed,
    });
  }

  // 过滤 Todo
  filterTodos(filter: 'all' | 'completed' | 'active'): Todo[] {
    switch (filter) {
      case 'completed':
        return this.todos.filter(todo => todo.completed);
      case 'active':
        return this.todos.filter(todo => !todo.completed);
      case 'all':
      default:
        return this.todos;
    }
  }
}

// 使用示例
const todoService = new TodoService();

// 创建 Todo
todoService.createTodo({
  title: 'Learn TypeScript',
  description: 'Study TypeScript basics and advanced features',
});

todoService.createTodo({
  title: 'Build a Todo app',
  description: 'Create a Todo application using TypeScript',
});

todoService.createTodo({
  title: 'Practice coding',
  description: 'Solve TypeScript exercises',
});

// 获取所有 Todo
console.log('All todos:', todoService.getTodos());

// 标记第一个 Todo 为完成
todoService.toggleTodo(1);

// 获取已完成的 Todo
console.log('Completed todos:', todoService.filterTodos('completed'));

// 获取未完成的 Todo
console.log('Active todos:', todoService.filterTodos('active'));

// 更新 Todo
todoService.updateTodo(2, {
  title: 'Build a TypeScript Todo app',
  description: 'Create a Todo application using TypeScript and React',
});

// 删除 Todo
todoService.deleteTodo(3);

// 获取所有 Todo
console.log('All todos after updates:', todoService.getTodos());

实战:完整的 TypeScript 应用

示例:电商购物车应用

typescript
// 定义产品类型
export interface Product {
  id: number;
  name: string;
  price: number;
  description: string;
  category: string;
  stock: number;
  imageUrl: string;
}

// 定义购物车项类型
export interface CartItem {
  product: Product;
  quantity: number;
}

// 定义购物车服务
class CartService {
  private items: CartItem[] = [];

  // 获取购物车项目
  getItems(): CartItem[] {
    return this.items;
  }

  // 获取购物车总数量
  getTotalQuantity(): number {
    return this.items.reduce((total, item) => total + item.quantity, 0);
  }

  // 获取购物车总金额
  getTotalPrice(): number {
    return this.items.reduce((total, item) => total + (item.product.price * item.quantity), 0);
  }

  // 添加商品到购物车
  addItem(product: Product, quantity: number = 1): void {
    const existingItem = this.items.find(item => item.product.id === product.id);

    if (existingItem) {
      // 如果商品已存在,增加数量
      existingItem.quantity += quantity;
    } else {
      // 如果商品不存在,添加新项
      this.items.push({ product, quantity });
    }
  }

  // 从购物车移除商品
  removeItem(productId: number): void {
    this.items = this.items.filter(item => item.product.id !== productId);
  }

  // 更新购物车项数量
  updateQuantity(productId: number, quantity: number): void {
    const item = this.items.find(item => item.product.id === productId);
    
    if (item) {
      if (quantity <= 0) {
        // 如果数量为 0 或负数,移除商品
        this.removeItem(productId);
      } else {
        // 更新数量
        item.quantity = quantity;
      }
    }
  }

  // 清空购物车
  clearCart(): void {
    this.items = [];
  }
}

// 定义产品服务
class ProductService {
  private products: Product[] = [
    {
      id: 1,
      name: 'iPhone 13',
      price: 799,
      description: 'Apple iPhone 13 with A15 Bionic chip',
      category: 'Electronics',
      stock: 100,
      imageUrl: 'https://example.com/iphone13.jpg',
    },
    {
      id: 2,
      name: 'MacBook Pro',
      price: 1299,
      description: 'Apple MacBook Pro with M1 chip',
      category: 'Electronics',
      stock: 50,
      imageUrl: 'https://example.com/macbookpro.jpg',
    },
    {
      id: 3,
      name: 'AirPods Pro',
      price: 199,
      description: 'Apple AirPods Pro with active noise cancellation',
      category: 'Electronics',
      stock: 200,
      imageUrl: 'https://example.com/airpodspro.jpg',
    },
  ];

  // 获取所有产品
  getProducts(): Product[] {
    return this.products;
  }

  // 根据 ID 获取产品
  getProductById(id: number): Product | undefined {
    return this.products.find(product => product.id === id);
  }

  // 根据分类获取产品
  getProductsByCategory(category: string): Product[] {
    return this.products.filter(product => product.category === category);
  }

  // 搜索产品
  searchProducts(query: string): Product[] {
    const lowerQuery = query.toLowerCase();
    return this.products.filter(product => 
      product.name.toLowerCase().includes(lowerQuery) ||
      product.description.toLowerCase().includes(lowerQuery)
    );
  }
}

// 使用示例
const productService = new ProductService();
const cartService = new CartService();

// 获取所有产品
console.log('All products:', productService.getProducts());

// 添加商品到购物车
const product1 = productService.getProductById(1);
const product2 = productService.getProductById(2);

if (product1 && product2) {
  cartService.addItem(product1, 2);
  cartService.addItem(product2, 1);
}

// 获取购物车
console.log('Cart items:', cartService.getItems());
console.log('Total quantity:', cartService.getTotalQuantity());
console.log('Total price:', cartService.getTotalPrice());

// 更新购物车项数量
cartService.updateQuantity(1, 3);
console.log('Cart items after update:', cartService.getItems());
console.log('Total quantity after update:', cartService.getTotalQuantity());
console.log('Total price after update:', cartService.getTotalPrice());

// 移除商品
cartService.removeItem(2);
console.log('Cart items after removal:', cartService.getItems());
console.log('Total quantity after removal:', cartService.getTotalQuantity());
console.log('Total price after removal:', cartService.getTotalPrice());

// 清空购物车
cartService.clearCart();
console.log('Cart items after clear:', cartService.getItems());
console.log('Total quantity after clear:', cartService.getTotalQuantity());
console.log('Total price after clear:', cartService.getTotalPrice());

小结

本章节通过几个综合案例,展示了 TypeScript 在实际项目中的应用:

  • 接口定义接口数据结构:定义了用户、产品、订单等接口数据结构
  • 函数封装 + 泛型工具:封装了通用 API 客户端,使用泛型提高代码复用性
  • 类封装业务逻辑:创建了用户管理服务,封装了用户相关的业务逻辑
  • 类型约束表单数据:实现了表单验证服务,确保表单数据的类型安全
  • TS 写一个 TodoList:创建了 TodoList 应用,展示了 TypeScript 在状态管理中的应用
  • 实战:完整的 TypeScript 应用:实现了电商购物车应用,展示了 TypeScript 在复杂应用中的应用

通过这些案例,你可以看到 TypeScript 如何帮助你构建类型安全、可维护的应用。在实际开发中,应该充分利用 TypeScript 的类型系统,提高代码的可靠性和可维护性。

© 2026 编程马·菜鸟教程 版权所有