Ts Comprehensive Project
π
2026-06-22 | π TypeScript
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"