YouTip LogoYouTip

Ts Comprehensive Project

This tutorial comprehensively applies various features of TypeScript through a complete project case. From project setup to actual development, it fully demonstrates the application of TypeScript in real projects. * * * * * * ## Why Comprehensive Project Practice Is Needed After learning TypeScript syntax, it is necessary to consolidate knowledge through practical projects. This tutorial showcases a complete task management system, covering frontend, backend, and type definitions. Through this project, you can master best practices for using TypeScript in actual development. > **Project Goal:** Create a task management system with functions for task creation, querying, updating, and deletion. * * * ## Project Structure Organize the project structure using Monorepo style. ## Directory Structure task-manager/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ types/ # Type Definitions β”‚ β”‚ β”œβ”€β”€ task.ts # Task Types β”‚ β”‚ β”œβ”€β”€ api.ts# API Types β”‚ β”‚ └── index.ts# Type Exports β”‚ β”‚ β”‚ β”œβ”€β”€ services/ # Service Layer β”‚ β”‚ β”œβ”€β”€ taskService.ts # Task Service β”‚ β”‚ └── index.ts β”‚ β”‚ β”‚ β”œβ”€β”€ components/ # React Components β”‚ β”‚ β”œβ”€β”€ TaskList.tsx # Task List β”‚ β”‚ β”œβ”€β”€ TaskItem.tsx # Task Item β”‚ β”‚ β”œβ”€β”€ TaskForm.tsx # Task Form β”‚ β”‚ └── index.ts β”‚ β”‚ β”‚ β”œβ”€β”€ hooks/# Custom Hooks β”‚ β”‚ β”œβ”€β”€ useTasks.ts# Task State Management β”‚ β”‚ └── index.ts β”‚ β”‚ β”‚ β”œβ”€β”€ App.tsx # Main Application β”‚ β”œβ”€β”€ App.css # Styles β”‚ └── main.tsx# Entry File β”‚ β”œβ”€β”€ index.html β”œβ”€β”€ package.json β”œβ”€β”€ tsconfig.json └── vite.config.ts > **Directory Division:** Directories are divided by functionality, separating type definitions, service layer, and components. * * * ## Type Definitions First, define the core types of the project. ## src/types/task.ts // Task Status Enum export type TaskStatus ="pending"|"in-progress"|"completed"; // Task Priority Enum export type TaskPriority ="low"|"medium"|"high"; // Task Interface Definition export interface Task { id: string;// Task ID title: string;// Task Title description?: string;// Task Description (Optional) status: TaskStatus;// Task Status priority: TaskPriority;// Task Priority createdAt: string;// Creation Time updatedAt: string;// Update Time dueDate?: string;// Due Date (Optional) tags?: string[];// Tags (Optional) } // Input Type for Creating Tasks export interface CreateTaskInput { title: string; description?: string; priority: TaskPriority; dueDate?: string; tags?: string[]; } // Input Type for Updating Tasks export interface UpdateTaskInput { title?: string; description?: string; status?: TaskStatus; priority?: TaskPriority; dueDate?: string; tags?: string[]; } // Task Filter Options export interface TaskFilter { status?: TaskStatus; priority?: TaskPriority; search?: string; } > **Type Hierarchy:** Separately define input types, output types, and filter types for easier maintenance. * * * ## API Type Definitions Define types related to APIs.

src/types/api.ts // General API Response Type export interface ApiResponse{ success:boolean; data?: T; error?: string; message?: string; } // Pagination Metadata export interface PaginationMeta { total: number; page: number; pageSize: number; totalPages: number; } // Paginated Response Type export interface PaginatedResponse{ items: T[]; meta: PaginationMeta; } // Request Error Type export interface ApiError { code: string; message: string; details?: Record; } // HTTP Method Types export type HttpMethod ="GET"|"POST"|"PUT"|"PATCH"|"DELETE"; // API Endpoints Related to Tasks export interface TaskEndpoints { getAll:"/api/tasks"; getById:"/api/tasks/:id"; create:"/api/tasks"; update:"/api/tasks/:id"; delete:"/api/tasks/:id"; } > **API Types:** Unified response format and error handling types facilitate front-end and back-end integration. * * * ## Task Service Layer Implement business logic for task management. ## src/services/taskService.ts // Import Type Definitions import{ Task, CreateTaskInput, UpdateTaskInput, TaskFilter, TaskStatus, TaskPriority } from "../types/task"; // Generate Unique ID function generateId(): string { return Date.now().toString(36)+Math.random().toString(36).substr(2); } // Simulate Database (Memory Storage) let tasks: Task[]=[ { id:"1", title:"Learn TypeScript", description:"Master basic and advanced features of TypeScript", status:"completed", priority:"high", createdAt:new Date().toISOString(), updatedAt:new Date().toISOString(), tags:["Learning","TypeScript"] }, { id:"2", title:"Develop Task Management System", description:"Develop using React + TypeScript", status:"in-progress", priority:"high", createdAt:new Date().toISOString(), updatedAt:new Date().toISOString(), tags:["Project","Practice"] } ]; // Task Service Class class TaskService { // Get All Tasks 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; } // Get Task by ID getById(id: string): Task |undefined{ return tasks.find(t => t.id=== id); } // Create Task 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 Task update(id: string, input: UpdateTaskInput): Task |null{ const index = tasks.findIndex(t => t.id=== id); if(index ===-1)return null; const task = tasks; const updated: Task ={ ...task, ...input, updatedAt:new Date().toISOString() }; tasks= updated; return updated; } // Delete Task delete(id: string):boolean{ const index = tasks.findIndex(t => t.id=== id); if(index ===-1)return false; tasks.splice(index,1); return true; } // Update Task Status updateStatus(id: string, status: TaskStatus): Task |null{ return this.update(id,{ status }); } } // Export Service Instance export const taskService =new TaskService(); > **Service Layer:** Business logic is centralized in the service layer, facilitating testing and maintenance. * * * ## Custom Hooks Use Hooks to manage task state.

src/hooks/useTasks.ts // Import React Hooks and Types import{ useState, useEffect, useCallback } from "react"; import{ Task, CreateTaskInput, UpdateTaskInput, TaskFilter, TaskStatus, TaskPriority } from "../types/task"; import{ taskService } from "../services/taskService"; // Return Type for Hook interface UseTasksReturn { tasks: Task[]; loading:boolean; error: string |null; filter: TaskFilter; // Operation Methods 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; } // Initialize Default Filter const defaultFilter: TaskFilter ={}; export function useTasks(): UseTasksReturn { // Task List State const[tasks, setTasks]= useState([]); // Loading State const[loading, setLoading]= useState(true); // Error State const[error, setError]= useState(null); // Filter Conditions const[filter, setFilter]= useState(defaultFilter); // Load Task List const loadTasks = useCallback(()=>{ setLoading(true); setError(null); try{ const data = taskService.getAll(filter); setTasks(data); }catch(err){ setError(err instanceof Error ? err.message:"Loading failed"); }finally{ setLoading(false); } },); // Initial Load and Reload on Filter Change useEffect(()=>{ loadTasks(); },); // Create Task const createTask = useCallback(async (input: CreateTaskInput)=>{ try{ taskService.create(input); loadTasks(); }catch(err){ setError(err instanceof Error ? err.message:"Creation failed"); } },); // Update Task const updateTask = useCallback(async (id: string, input: UpdateTaskInput)=>{ try{ taskService.update(id, input); loadTasks(); }catch(err){ setError(err instanceof Error ? err.message:"Update failed"); } },); // Delete Task const deleteTask = useCallback(async (id: string)=>{ try{ taskService.delete(id); loadTasks(); }catch(err){ setError(err instanceof Error ? err.message:"Deletion failed"); } },); // Update Task Status const updateStatus = useCallback(async (id: string, status: TaskStatus)=>{ try{ taskService.updateStatus(id, status); loadTasks(); }catch(err){ setError(err instanceof Error ? err.message:"Status update failed"); } },); // Refresh Task List const refresh = useCallback(()=>{ loadTasks(); },); return{ tasks, loading, error, filter, createTask, updateTask, deleteTask, updateStatus, setFilter, refresh }; } > **Custom Hooks:** Encapsulate state management and business logic within Hooks to make components cleaner. * * * ## React Components Create task list components using Hooks. ## src/components/TaskList.tsx // Import React and Custom Hook import React from "react"

← Ts Vue3Ts Design Patterns β†’