TypeScript实战指南:从基础语法到高级应用的完整开发之路

🎯 引言

TypeScript作为JavaScript的超集,为前端开发带来了强类型系统的优势,显著提升了代码的可维护性和开发效率。本文将从基础语法开始,逐步深入到高级特性和实际应用,帮助你全面掌握TypeScript开发技能。

📚 目录结构

1
2
3
4
5
6
7
8
9
10
11
12
typescript-guide/
├── src/
│ ├── basic/ # 基础语法示例
│ ├── advanced/ # 高级特性
│ ├── patterns/ # 设计模式
│ ├── utils/ # 工具函数
│ └── examples/ # 实战示例
├── tests/ # 测试文件
├── docs/ # 文档
├── tsconfig.json # TypeScript配置
├── package.json # 项目配置
└── README.md # 项目说明

🔧 环境配置与项目初始化

1. 项目初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// package.json
{
"name": "typescript-guide",
"version": "1.0.0",
"description": "TypeScript实战指南",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"dev": "ts-node src/index.ts",
"test": "jest",
"test:watch": "jest --watch",
"lint": "eslint src/**/*.ts",
"lint:fix": "eslint src/**/*.ts --fix",
"format": "prettier --write src/**/*.ts"
},
"devDependencies": {
"@types/node": "^20.0.0",
"@types/jest": "^29.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.0.0",
"jest": "^29.0.0",
"prettier": "^3.0.0",
"ts-jest": "^29.0.0",
"ts-node": "^10.0.0",
"typescript": "^5.0.0"
},
"dependencies": {
"axios": "^1.0.0",
"lodash": "^4.17.21"
}
}

2. TypeScript配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020", "DOM"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@/types/*": ["src/types/*"],
"@/utils/*": ["src/utils/*"]
}
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist",
"**/*.test.ts"
]
}

🏗️ 基础语法与类型系统

1. 基本类型定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// src/basic/types.ts

// 基本类型
let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
let list: number[] = [1, 2, 3];
let tuple: [string, number] = ["hello", 10];

// 枚举类型
enum Color {
Red = 1,
Green = 2,
Blue = 4
}

enum Status {
Pending = "PENDING",
Approved = "APPROVED",
Rejected = "REJECTED"
}

// 联合类型
type StringOrNumber = string | number;
type Theme = "light" | "dark";

// 字面量类型
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type Size = "small" | "medium" | "large";

// 类型别名
type User = {
id: number;
name: string;
email: string;
age?: number; // 可选属性
readonly createdAt: Date; // 只读属性
};

// 索引签名
type Dictionary<T> = {
[key: string]: T;
};

type NumberDictionary = Dictionary<number>;
type StringDictionary = Dictionary<string>;

// 函数类型
type Calculator = (a: number, b: number) => number;
type EventHandler<T> = (event: T) => void;
type AsyncFunction<T> = () => Promise<T>;

// 条件类型
type NonNullable<T> = T extends null | undefined ? never : T;
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

// 映射类型
type Partial<T> = {
[P in keyof T]?: T[P];
};

type Required<T> = {
[P in keyof T]-?: T[P];
};

type Readonly<T> = {
readonly [P in keyof T]: T[P];
};

// 实用工具类型示例
interface UserProfile {
id: number;
name: string;
email: string;
avatar?: string;
settings: {
theme: Theme;
notifications: boolean;
};
}

type PartialUserProfile = Partial<UserProfile>;
type RequiredUserProfile = Required<UserProfile>;
type UserProfileKeys = keyof UserProfile;
type UserEmail = Pick<UserProfile, 'email'>;
type UserWithoutId = Omit<UserProfile, 'id'>;

2. 接口定义与继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// src/basic/interfaces.ts

// 基础接口
interface Animal {
name: string;
age: number;
makeSound(): string;
}

// 接口继承
interface Dog extends Animal {
breed: string;
wagTail(): void;
}

interface Cat extends Animal {
indoor: boolean;
purr(): void;
}

// 多重继承
interface Pet extends Animal {
owner: string;
vaccinated: boolean;
}

interface ServiceAnimal extends Pet {
serviceType: string;
certified: boolean;
}

// 接口合并
interface Window {
title: string;
}

interface Window {
ts: TypeScriptAPI;
}

// 函数接口
interface SearchFunc {
(source: string, subString: string): boolean;
}

interface EventListener<T = Event> {
(event: T): void;
}

// 可索引接口
interface StringArray {
[index: number]: string;
}

interface NumberDictionary {
[index: string]: number;
length: number; // 可以,length是number类型
name: string; // 错误,name的类型与索引类型返回值的类型不匹配
}

// 类接口
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}

class Clock implements ClockInterface {
currentTime: Date = new Date();

setTime(d: Date) {
this.currentTime = d;
}

constructor(h: number, m: number) {}
}

// 构造器接口
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}

interface ClockInterface {
tick(): void;
}

function createClock(
ctor: ClockConstructor,
hour: number,
minute: number
): ClockInterface {
return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
constructor(h: number, m: number) {}
tick() {
console.log("beep beep");
}
}

class AnalogClock implements ClockInterface {
constructor(h: number, m: number) {}
tick() {
console.log("tick tock");
}
}

// 混合类型接口
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}

function getCounter(): Counter {
let counter = function (start: number) {
return `Started at ${start}`;
} as Counter;

counter.interval = 123;
counter.reset = function () {
console.log("Counter reset");
};

return counter;
}

🎨 类与面向对象编程

1. 类的定义与继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// src/basic/classes.ts

// 基础类定义
abstract class Shape {
protected name: string;
protected color: string;

constructor(name: string, color: string) {
this.name = name;
this.color = color;
}

// 抽象方法
abstract calculateArea(): number;
abstract calculatePerimeter(): number;

// 具体方法
getInfo(): string {
return `${this.name} (${this.color})`;
}

// 静态方法
static compareAreas(shape1: Shape, shape2: Shape): number {
return shape1.calculateArea() - shape2.calculateArea();
}
}

// 继承实现
class Rectangle extends Shape {
private width: number;
private height: number;

constructor(width: number, height: number, color: string = "white") {
super("Rectangle", color);
this.width = width;
this.height = height;
}

calculateArea(): number {
return this.width * this.height;
}

calculatePerimeter(): number {
return 2 * (this.width + this.height);
}

// Getter和Setter
get area(): number {
return this.calculateArea();
}

get dimensions(): { width: number; height: number } {
return { width: this.width, height: this.height };
}

set dimensions(dims: { width: number; height: number }) {
this.width = dims.width;
this.height = dims.height;
}
}

class Circle extends Shape {
private radius: number;

constructor(radius: number, color: string = "white") {
super("Circle", color);
this.radius = radius;
}

calculateArea(): number {
return Math.PI * this.radius ** 2;
}

calculatePerimeter(): number {
return 2 * Math.PI * this.radius;
}

get diameter(): number {
return this.radius * 2;
}
}

// 访问修饰符示例
class BankAccount {
public readonly accountNumber: string;
private balance: number;
protected interestRate: number;

constructor(accountNumber: string, initialBalance: number) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
this.interestRate = 0.02;
}

public deposit(amount: number): void {
if (amount > 0) {
this.balance += amount;
}
}

public withdraw(amount: number): boolean {
if (amount > 0 && amount <= this.balance) {
this.balance -= amount;
return true;
}
return false;
}

public getBalance(): number {
return this.balance;
}

protected calculateInterest(): number {
return this.balance * this.interestRate;
}
}

class SavingsAccount extends BankAccount {
private minimumBalance: number;

constructor(accountNumber: string, initialBalance: number, minimumBalance: number) {
super(accountNumber, initialBalance);
this.minimumBalance = minimumBalance;
}

public withdraw(amount: number): boolean {
const newBalance = this.getBalance() - amount;
if (newBalance >= this.minimumBalance) {
return super.withdraw(amount);
}
return false;
}

public addInterest(): void {
const interest = this.calculateInterest();
this.deposit(interest);
}
}

// 参数属性简化写法
class Person {
constructor(
public readonly id: number,
public name: string,
private age: number,
protected email: string
) {}

getAge(): number {
return this.age;
}

setAge(age: number): void {
if (age >= 0) {
this.age = age;
}
}
}

// 单例模式实现
class DatabaseConnection {
private static instance: DatabaseConnection;
private connected: boolean = false;

private constructor() {}

public static getInstance(): DatabaseConnection {
if (!DatabaseConnection.instance) {
DatabaseConnection.instance = new DatabaseConnection();
}
return DatabaseConnection.instance;
}

public connect(): void {
if (!this.connected) {
this.connected = true;
console.log("Database connected");
}
}

public disconnect(): void {
if (this.connected) {
this.connected = false;
console.log("Database disconnected");
}
}

public isConnected(): boolean {
return this.connected;
}
}

🔥 泛型编程

1. 泛型基础与约束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// src/advanced/generics.ts

// 基础泛型函数
function identity<T>(arg: T): T {
return arg;
}

function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}

// 泛型约束
interface Lengthwise {
length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}

// 使用类型参数
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}

// 泛型类
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;

constructor(zeroValue: T, addFn: (x: T, y: T) => T) {
this.zeroValue = zeroValue;
this.add = addFn;
}
}

// 数据结构泛型实现
class Stack<T> {
private items: T[] = [];

push(item: T): void {
this.items.push(item);
}

pop(): T | undefined {
return this.items.pop();
}

peek(): T | undefined {
return this.items[this.items.length - 1];
}

isEmpty(): boolean {
return this.items.length === 0;
}

size(): number {
return this.items.length;
}

clear(): void {
this.items = [];
}

toArray(): T[] {
return [...this.items];
}
}

class Queue<T> {
private items: T[] = [];

enqueue(item: T): void {
this.items.push(item);
}

dequeue(): T | undefined {
return this.items.shift();
}

front(): T | undefined {
return this.items[0];
}

isEmpty(): boolean {
return this.items.length === 0;
}

size(): number {
return this.items.length;
}
}

// 泛型接口
interface Repository<T> {
findById(id: string): Promise<T | null>;
findAll(): Promise<T[]>;
create(entity: Omit<T, 'id'>): Promise<T>;
update(id: string, entity: Partial<T>): Promise<T | null>;
delete(id: string): Promise<boolean>;
}

interface Serializable {
serialize(): string;
}

interface Deserializable<T> {
deserialize(data: string): T;
}

// 高级泛型模式
type ApiResponse<T> = {
data: T;
status: number;
message: string;
timestamp: Date;
};

type PaginatedResponse<T> = ApiResponse<{
items: T[];
total: number;
page: number;
pageSize: number;
}>;

// 条件类型与泛型
type NonNullable<T> = T extends null | undefined ? never : T;
type ElementType<T> = T extends (infer U)[] ? U : never;
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

// 映射类型与泛型
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};

// 实用泛型工具
class Result<T, E = Error> {
private constructor(
private readonly _value?: T,
private readonly _error?: E,
private readonly _isSuccess: boolean = true
) {}

static success<T>(value: T): Result<T> {
return new Result(value, undefined, true);
}

static failure<E>(error: E): Result<never, E> {
return new Result(undefined, error, false);
}

isSuccess(): boolean {
return this._isSuccess;
}

isFailure(): boolean {
return !this._isSuccess;
}

getValue(): T {
if (!this._isSuccess) {
throw new Error("Cannot get value from failed result");
}
return this._value!;
}

getError(): E {
if (this._isSuccess) {
throw new Error("Cannot get error from successful result");
}
return this._error!;
}

map<U>(fn: (value: T) => U): Result<U, E> {
if (this._isSuccess) {
try {
return Result.success(fn(this._value!));
} catch (error) {
return Result.failure(error as E);
}
}
return Result.failure(this._error!);
}

flatMap<U>(fn: (value: T) => Result<U, E>): Result<U, E> {
if (this._isSuccess) {
return fn(this._value!);
}
return Result.failure(this._error!);
}
}

// 泛型工厂模式
interface Factory<T> {
create(...args: any[]): T;
}

class UserFactory implements Factory<User> {
create(name: string, email: string): User {
return {
id: Math.random().toString(36),
name,
email,
createdAt: new Date()
};
}
}

class ProductFactory implements Factory<Product> {
create(name: string, price: number): Product {
return {
id: Math.random().toString(36),
name,
price,
createdAt: new Date()
};
}
}

// 类型推断辅助
function createArray<T>(length: number, value: T): T[] {
return Array(length).fill(value);
}

function pipe<T>(...fns: Array<(arg: T) => T>) {
return (value: T): T => fns.reduce((acc, fn) => fn(acc), value);
}

function compose<T>(...fns: Array<(arg: T) => T>) {
return (value: T): T => fns.reduceRight((acc, fn) => fn(acc), value);
}

2. 高级泛型应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// src/advanced/advanced-generics.ts

// 递归泛型类型
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

type DeepRequired<T> = {
[P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
};

// 字符串模板字面量类型
type EventName<T extends string> = `on${Capitalize<T>}`;
type HttpUrl<T extends string> = `https://${T}`;
type ApiEndpoint<T extends string> = `/api/v1/${T}`;

// 键值映射类型
type KeyValuePair<T> = {
[K in keyof T]: {
key: K;
value: T[K];
};
}[keyof T];

// 函数重载泛型
function createElement(tag: 'div'): HTMLDivElement;
function createElement(tag: 'span'): HTMLSpanElement;
function createElement(tag: 'input'): HTMLInputElement;
function createElement<T extends keyof HTMLElementTagNameMap>(
tag: T
): HTMLElementTagNameMap[T];
function createElement(tag: string): HTMLElement {
return document.createElement(tag);
}

// 高阶函数泛型
type Middleware<T> = (input: T) => T | Promise<T>;

class Pipeline<T> {
private middlewares: Middleware<T>[] = [];

use(middleware: Middleware<T>): this {
this.middlewares.push(middleware);
return this;
}

async execute(input: T): Promise<T> {
let result = input;
for (const middleware of this.middlewares) {
result = await middleware(result);
}
return result;
}
}

// 状态机泛型
type StateMachine<S extends string, E extends string> = {
currentState: S;
transitions: Record<S, Partial<Record<E, S>>>;
transition(event: E): boolean;
canTransition(event: E): boolean;
};

function createStateMachine<S extends string, E extends string>(
initialState: S,
transitions: Record<S, Partial<Record<E, S>>>
): StateMachine<S, E> {
return {
currentState: initialState,
transitions,

transition(event: E): boolean {
const nextState = this.transitions[this.currentState]?.[event];
if (nextState) {
this.currentState = nextState;
return true;
}
return false;
},

canTransition(event: E): boolean {
return !!this.transitions[this.currentState]?.[event];
}
};
}

// 使用示例
type OrderState = 'pending' | 'confirmed' | 'shipped' | 'delivered' | 'cancelled';
type OrderEvent = 'confirm' | 'ship' | 'deliver' | 'cancel';

const orderStateMachine = createStateMachine<OrderState, OrderEvent>('pending', {
pending: { confirm: 'confirmed', cancel: 'cancelled' },
confirmed: { ship: 'shipped', cancel: 'cancelled' },
shipped: { deliver: 'delivered' },
delivered: {},
cancelled: {}
});

// 观察者模式泛型
interface Observer<T> {
update(data: T): void;
}

interface Observable<T> {
subscribe(observer: Observer<T>): void;
unsubscribe(observer: Observer<T>): void;
notify(data: T): void;
}

class EventEmitter<T extends Record<string, any>> implements Observable<T> {
private observers: Map<keyof T, Observer<T[keyof T]>[]> = new Map();

subscribe<K extends keyof T>(event: K, observer: Observer<T[K]>): void {
if (!this.observers.has(event)) {
this.observers.set(event, []);
}
this.observers.get(event)!.push(observer as Observer<T[keyof T]>);
}

unsubscribe<K extends keyof T>(event: K, observer: Observer<T[K]>): void {
const observers = this.observers.get(event);
if (observers) {
const index = observers.indexOf(observer as Observer<T[keyof T]>);
if (index > -1) {
observers.splice(index, 1);
}
}
}

notify<K extends keyof T>(event: K, data: T[K]): void {
const observers = this.observers.get(event);
if (observers) {
observers.forEach(observer => observer.update(data));
}
}
}

// 类型安全的事件系统
type AppEvents = {
userLogin: { userId: string; timestamp: Date };
userLogout: { userId: string };
dataUpdate: { table: string; id: string; data: any };
};

const eventEmitter = new EventEmitter<AppEvents>();

// 类型安全的订阅
eventEmitter.subscribe('userLogin', {
update(data) {
console.log(`User ${data.userId} logged in at ${data.timestamp}`);
}
});

🎭 装饰器与元编程

1. 装饰器基础

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// src/advanced/decorators.ts

// 类装饰器
function Entity(tableName: string) {
return function <T extends { new (...args: any[]): {} }>(constructor: T) {
return class extends constructor {
tableName = tableName;

save() {
console.log(`Saving to table: ${tableName}`);
}
};
};
}

function Singleton<T extends { new (...args: any[]): {} }>(constructor: T) {
let instance: T;

return class extends constructor {
constructor(...args: any[]) {
if (instance) {
return instance;
}
super(...args);
instance = this as any;
return instance;
}
} as T;
}

// 方法装饰器
function Log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;

descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyName} with arguments:`, args);
const result = method.apply(this, args);
console.log(`Method ${propertyName} returned:`, result);
return result;
};
}

function Throttle(delay: number) {
return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;
let timeoutId: NodeJS.Timeout | null = null;

descriptor.value = function (...args: any[]) {
if (timeoutId) {
clearTimeout(timeoutId);
}

timeoutId = setTimeout(() => {
method.apply(this, args);
timeoutId = null;
}, delay);
};
};
}

function Retry(maxAttempts: number = 3) {
return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;

descriptor.value = async function (...args: any[]) {
let attempts = 0;

while (attempts < maxAttempts) {
try {
return await method.apply(this, args);
} catch (error) {
attempts++;
if (attempts >= maxAttempts) {
throw error;
}
console.log(`Attempt ${attempts} failed, retrying...`);
}
}
};
};
}

// 属性装饰器
function Required(target: any, propertyName: string) {
let value: any;

const getter = () => {
return value;
};

const setter = (newValue: any) => {
if (newValue === null || newValue === undefined) {
throw new Error(`Property ${propertyName} is required`);
}
value = newValue;
};

Object.defineProperty(target, propertyName, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}

function Range(min: number, max: number) {
return function (target: any, propertyName: string) {
let value: number;

const getter = () => value;
const setter = (newValue: number) => {
if (newValue < min || newValue > max) {
throw new Error(`Property ${propertyName} must be between ${min} and ${max}`);
}
value = newValue;
};

Object.defineProperty(target, propertyName, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
};
}

// 参数装饰器
function Validate(target: any, propertyName: string, parameterIndex: number) {
const existingValidators = Reflect.getMetadata('validators', target, propertyName) || [];
existingValidators.push(parameterIndex);
Reflect.defineMetadata('validators', existingValidators, target, propertyName);
}

// 装饰器应用示例
@Entity('users')
@Singleton
class User {
@Required
public name: string;

@Range(0, 120)
public age: number;

constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

@Log
@Retry(3)
async fetchData(): Promise<string> {
// 模拟可能失败的异步操作
if (Math.random() < 0.7) {
throw new Error('Network error');
}
return 'Data fetched successfully';
}

@Throttle(1000)
onScroll() {
console.log('Scroll event handled');
}
}

// 高级装饰器模式
class MetadataManager {
private static metadata = new WeakMap();

static setMetadata(key: string, value: any, target: any, propertyKey?: string) {
if (!this.metadata.has(target)) {
this.metadata.set(target, new Map());
}

const targetMetadata = this.metadata.get(target);
const metadataKey = propertyKey ? `${key}:${propertyKey}` : key;
targetMetadata.set(metadataKey, value);
}

static getMetadata(key: string, target: any, propertyKey?: string): any {
if (!this.metadata.has(target)) {
return undefined;
}

const targetMetadata = this.metadata.get(target);
const metadataKey = propertyKey ? `${key}:${propertyKey}` : key;
return targetMetadata.get(metadataKey);
}
}

// 验证装饰器系统
type ValidationRule = (value: any) => boolean | string;

const validationRules = new Map<string, ValidationRule[]>();

function IsEmail(target: any, propertyName: string) {
const rules = validationRules.get(propertyName) || [];
rules.push((value: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(value) || 'Invalid email format';
});
validationRules.set(propertyName, rules);
}

function MinLength(length: number) {
return function (target: any, propertyName: string) {
const rules = validationRules.get(propertyName) || [];
rules.push((value: string) => {
return value.length >= length || `Minimum length is ${length}`;
});
validationRules.set(propertyName, rules);
};
}

function validate(obj: any): { isValid: boolean; errors: string[] } {
const errors: string[] = [];

for (const [propertyName, rules] of validationRules) {
const value = obj[propertyName];

for (const rule of rules) {
const result = rule(value);
if (typeof result === 'string') {
errors.push(`${propertyName}: ${result}`);
}
}
}

return {
isValid: errors.length === 0,
errors
};
}

class UserRegistration {
@IsEmail
email: string;

@MinLength(8)
password: string;

constructor(email: string, password: string) {
this.email = email;
this.password = password;
}
}

2. 依赖注入装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// src/advanced/dependency-injection.ts

// 依赖注入容器
class Container {
private services = new Map<string, any>();
private singletons = new Map<string, any>();

register<T>(token: string, factory: () => T, singleton: boolean = false): void {
this.services.set(token, { factory, singleton });
}

resolve<T>(token: string): T {
const service = this.services.get(token);
if (!service) {
throw new Error(`Service ${token} not found`);
}

if (service.singleton) {
if (!this.singletons.has(token)) {
this.singletons.set(token, service.factory());
}
return this.singletons.get(token);
}

return service.factory();
}
}

const container = new Container();

// 装饰器
function Injectable(token: string) {
return function <T extends { new (...args: any[]): {} }>(constructor: T) {
container.register(token, () => new constructor(), false);
return constructor;
};
}

function Singleton(token: string) {
return function <T extends { new (...args: any[]): {} }>(constructor: T) {
container.register(token, () => new constructor(), true);
return constructor;
};
}

function Inject(token: string) {
return function (target: any, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
get: () => container.resolve(token),
enumerable: true,
configurable: true
});
};
}

// 服务定义
interface ILogger {
log(message: string): void;
}

interface IUserRepository {
findById(id: string): Promise<User | null>;
save(user: User): Promise<void>;
}

@Injectable('logger')
class ConsoleLogger implements ILogger {
log(message: string): void {
console.log(`[${new Date().toISOString()}] ${message}`);
}
}

@Singleton('userRepository')
class UserRepository implements IUserRepository {
private users: User[] = [];

async findById(id: string): Promise<User | null> {
return this.users.find(user => user.id === id) || null;
}

async save(user: User): Promise<void> {
const existingIndex = this.users.findIndex(u => u.id === user.id);
if (existingIndex >= 0) {
this.users[existingIndex] = user;
} else {
this.users.push(user);
}
}
}

@Injectable('userService')
class UserService {
@Inject('logger')
private logger: ILogger;

@Inject('userRepository')
private userRepository: IUserRepository;

async createUser(name: string, email: string): Promise<User> {
this.logger.log(`Creating user: ${name}`);

const user = new User(name, email);
await this.userRepository.save(user);

this.logger.log(`User created with ID: ${user.id}`);
return user;
}

async getUser(id: string): Promise<User | null> {
this.logger.log(`Fetching user: ${id}`);
return await this.userRepository.findById(id);
}
}

📦 模块化与命名空间

1. 模块系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// src/modules/types.ts
export interface User {
id: string;
name: string;
email: string;
createdAt: Date;
}

export interface Product {
id: string;
name: string;
price: number;
category: string;
inStock: boolean;
}

export type ApiResponse<T> = {
success: boolean;
data: T;
message?: string;
};

export enum UserRole {
Admin = 'admin',
User = 'user',
Guest = 'guest'
}

// src/modules/utils.ts
export class ValidationUtils {
static isEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}

static isStrongPassword(password: string): boolean {
const strongPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
return strongPasswordRegex.test(password);
}

static sanitizeString(input: string): string {
return input.replace(/[<>]/g, '');
}
}

export class DateUtils {
static formatDate(date: Date, format: string = 'YYYY-MM-DD'): string {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');

return format
.replace('YYYY', year.toString())
.replace('MM', month)
.replace('DD', day);
}

static addDays(date: Date, days: number): Date {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}

static diffInDays(date1: Date, date2: Date): number {
const timeDiff = Math.abs(date2.getTime() - date1.getTime());
return Math.ceil(timeDiff / (1000 * 3600 * 24));
}
}

// src/modules/http-client.ts
export class HttpClient {
private baseURL: string;
private defaultHeaders: Record<string, string>;

constructor(baseURL: string, defaultHeaders: Record<string, string> = {}) {
this.baseURL = baseURL;
this.defaultHeaders = defaultHeaders;
}

private async request<T>(
method: string,
url: string,
data?: any,
headers?: Record<string, string>
): Promise<ApiResponse<T>> {
const fullURL = `${this.baseURL}${url}`;
const requestHeaders = { ...this.defaultHeaders, ...headers };

try {
const response = await fetch(fullURL, {
method,
headers: {
'Content-Type': 'application/json',
...requestHeaders
},
body: data ? JSON.stringify(data) : undefined
});

const result = await response.json();

return {
success: response.ok,
data: result,
message: response.ok ? 'Success' : 'Request failed'
};
} catch (error) {
return {
success: false,
data: null as any,
message: error instanceof Error ? error.message : 'Unknown error'
};
}
}

async get<T>(url: string, headers?: Record<string, string>): Promise<ApiResponse<T>> {
return this.request<T>('GET', url, undefined, headers);
}

async post<T>(url: string, data: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {
return this.request<T>('POST', url, data, headers);
}

async put<T>(url: string, data: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {
return this.request<T>('PUT', url, data, headers);
}

async delete<T>(url: string, headers?: Record<string, string>): Promise<ApiResponse<T>> {
return this.request<T>('DELETE', url, undefined, headers);
}
}

// src/modules/user-service.ts
import { User, ApiResponse } from './types';
import { HttpClient } from './http-client';
import { ValidationUtils } from './utils';

export class UserService {
private httpClient: HttpClient;

constructor(baseURL: string) {
this.httpClient = new HttpClient(baseURL);
}

async createUser(userData: Omit<User, 'id' | 'createdAt'>): Promise<ApiResponse<User>> {
// 验证输入
if (!ValidationUtils.isEmail(userData.email)) {
return {
success: false,
data: null as any,
message: 'Invalid email format'
};
}

return this.httpClient.post<User>('/users', userData);
}

async getUserById(id: string): Promise<ApiResponse<User>> {
return this.httpClient.get<User>(`/users/${id}`);
}

async updateUser(id: string, userData: Partial<User>): Promise<ApiResponse<User>> {
return this.httpClient.put<User>(`/users/${id}`, userData);
}

async deleteUser(id: string): Promise<ApiResponse<void>> {
return this.httpClient.delete<void>(`/users/${id}`);
}

async getAllUsers(): Promise<ApiResponse<User[]>> {
return this.httpClient.get<User[]>('/users');
}
}

// src/modules/index.ts - 统一导出
export * from './types';
export * from './utils';
export * from './http-client';
export * from './user-service';

// 默认导出
export { UserService as default } from './user-service';

2. 命名空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// src/namespaces/geometry.ts
namespace Geometry {
export interface Point {
x: number;
y: number;
}

export interface Rectangle {
topLeft: Point;
width: number;
height: number;
}

export interface Circle {
center: Point;
radius: number;
}

export namespace Utils {
export function distance(p1: Point, p2: Point): number {
return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}

export function midpoint(p1: Point, p2: Point): Point {
return {
x: (p1.x + p2.x) / 2,
y: (p1.y + p2.y) / 2
};
}
}

export namespace Shapes {
export function rectangleArea(rect: Rectangle): number {
return rect.width * rect.height;
}

export function circleArea(circle: Circle): number {
return Math.PI * circle.radius * circle.radius;
}

export function rectanglePerimeter(rect: Rectangle): number {
return 2 * (rect.width + rect.height);
}

export function circlePerimeter(circle: Circle): number {
return 2 * Math.PI * circle.radius;
}
}
}

// 使用命名空间
const point1: Geometry.Point = { x: 0, y: 0 };
const point2: Geometry.Point = { x: 3, y: 4 };
const distance = Geometry.Utils.distance(point1, point2);

const rectangle: Geometry.Rectangle = {
topLeft: { x: 0, y: 0 },
width: 10,
height: 5
};
const area = Geometry.Shapes.rectangleArea(rectangle);

🚀 实战应用示例

1. 任务管理系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
// src/examples/task-manager.ts

// 类型定义
interface Task {
id: string;
title: string;
description: string;
status: TaskStatus;
priority: TaskPriority;
assignee?: string;
dueDate?: Date;
createdAt: Date;
updatedAt: Date;
tags: string[];
}

enum TaskStatus {
TODO = 'todo',
IN_PROGRESS = 'in_progress',
REVIEW = 'review',
DONE = 'done'
}

enum TaskPriority {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
URGENT = 'urgent'
}

interface TaskFilter {
status?: TaskStatus[];
priority?: TaskPriority[];
assignee?: string;
tags?: string[];
dueBefore?: Date;
dueAfter?: Date;
}

interface TaskStats {
total: number;
byStatus: Record<TaskStatus, number>;
byPriority: Record<TaskPriority, number>;
overdue: number;
}

// 任务管理器实现
class TaskManager {
private tasks: Map<string, Task> = new Map();
private observers: Array<(tasks: Task[]) => void> = [];

// 创建任务
createTask(taskData: Omit<Task, 'id' | 'createdAt' | 'updatedAt'>): Task {
const task: Task = {
...taskData,
id: this.generateId(),
createdAt: new Date(),
updatedAt: new Date()
};

this.tasks.set(task.id, task);
this.notifyObservers();

return task;
}

// 更新任务
updateTask(id: string, updates: Partial<Omit<Task, 'id' | 'createdAt'>>): Task | null {
const task = this.tasks.get(id);
if (!task) {
return null;
}

const updatedTask: Task = {
...task,
...updates,
updatedAt: new Date()
};

this.tasks.set(id, updatedTask);
this.notifyObservers();

return updatedTask;
}

// 删除任务
deleteTask(id: string): boolean {
const deleted = this.tasks.delete(id);
if (deleted) {
this.notifyObservers();
}
return deleted;
}

// 获取任务
getTask(id: string): Task | null {
return this.tasks.get(id) || null;
}

// 获取所有任务
getAllTasks(): Task[] {
return Array.from(this.tasks.values());
}

// 过滤任务
filterTasks(filter: TaskFilter): Task[] {
return this.getAllTasks().filter(task => {
if (filter.status && !filter.status.includes(task.status)) {
return false;
}

if (filter.priority && !filter.priority.includes(task.priority)) {
return false;
}

if (filter.assignee && task.assignee !== filter.assignee) {
return false;
}

if (filter.tags && !filter.tags.some(tag => task.tags.includes(tag))) {
return false;
}

if (filter.dueBefore && task.dueDate && task.dueDate > filter.dueBefore) {
return false;
}

if (filter.dueAfter && task.dueDate && task.dueDate < filter.dueAfter) {
return false;
}

return true;
});
}

// 搜索任务
searchTasks(query: string): Task[] {
const lowercaseQuery = query.toLowerCase();

return this.getAllTasks().filter(task =>
task.title.toLowerCase().includes(lowercaseQuery) ||
task.description.toLowerCase().includes(lowercaseQuery) ||
task.tags.some(tag => tag.toLowerCase().includes(lowercaseQuery))
);
}

// 获取统计信息
getStats(): TaskStats {
const tasks = this.getAllTasks();
const now = new Date();

const stats: TaskStats = {
total: tasks.length,
byStatus: {
[TaskStatus.TODO]: 0,
[TaskStatus.IN_PROGRESS]: 0,
[TaskStatus.REVIEW]: 0,
[TaskStatus.DONE]: 0
},
byPriority: {
[TaskPriority.LOW]: 0,
[TaskPriority.MEDIUM]: 0,
[TaskPriority.HIGH]: 0,
[TaskPriority.URGENT]: 0
},
overdue: 0
};

tasks.forEach(task => {
stats.byStatus[task.status]++;
stats.byPriority[task.priority]++;

if (task.dueDate && task.dueDate < now && task.status !== TaskStatus.DONE) {
stats.overdue++;
}
});

return stats;
}

// 批量操作
bulkUpdateStatus(taskIds: string[], status: TaskStatus): Task[] {
const updatedTasks: Task[] = [];

taskIds.forEach(id => {
const task = this.updateTask(id, { status });
if (task) {
updatedTasks.push(task);
}
});

return updatedTasks;
}

// 观察者模式
subscribe(observer: (tasks: Task[]) => void): void {
this.observers.push(observer);
}

unsubscribe(observer: (tasks: Task[]) => void): void {
const index = this.observers.indexOf(observer);
if (index > -1) {
this.observers.splice(index, 1);
}
}

private notifyObservers(): void {
const tasks = this.getAllTasks();
this.observers.forEach(observer => observer(tasks));
}

private generateId(): string {
return Math.random().toString(36).substr(2, 9);
}
}

// 使用示例
const taskManager = new TaskManager();

// 创建任务
const task1 = taskManager.createTask({
title: '实现用户认证',
description: '使用JWT实现用户登录和注册功能',
status: TaskStatus.TODO,
priority: TaskPriority.HIGH,
assignee: 'developer1',
dueDate: new Date('2025-08-01'),
tags: ['backend', 'security']
});

const task2 = taskManager.createTask({
title: '设计用户界面',
description: '创建响应式的用户界面设计',
status: TaskStatus.IN_PROGRESS,
priority: TaskPriority.MEDIUM,
assignee: 'designer1',
tags: ['frontend', 'ui']
});

// 订阅任务变更
taskManager.subscribe((tasks) => {
console.log(`任务总数: ${tasks.length}`);
});

// 过滤高优先级任务
const highPriorityTasks = taskManager.filterTasks({
priority: [TaskPriority.HIGH, TaskPriority.URGENT]
});

// 获取统计信息
const stats = taskManager.getStats();
console.log('任务统计:', stats);

2. 数据验证系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
// src/examples/validation-system.ts

// 验证规则接口
interface ValidationRule<T = any> {
validate(value: T): ValidationResult;
message?: string;
}

interface ValidationResult {
isValid: boolean;
message?: string;
}

interface ValidationSchema<T> {
[K in keyof T]?: ValidationRule<T[K]>[];
}

// 基础验证规则
class RequiredRule implements ValidationRule {
constructor(private message: string = 'This field is required') {}

validate(value: any): ValidationResult {
const isValid = value !== null && value !== undefined && value !== '';
return {
isValid,
message: isValid ? undefined : this.message
};
}
}

class MinLengthRule implements ValidationRule<string> {
constructor(
private minLength: number,
private message?: string
) {
this.message = message || `Minimum length is ${minLength}`;
}

validate(value: string): ValidationResult {
const isValid = value && value.length >= this.minLength;
return {
isValid,
message: isValid ? undefined : this.message
};
}
}

class MaxLengthRule implements ValidationRule<string> {
constructor(
private maxLength: number,
private message?: string
) {
this.message = message || `Maximum length is ${maxLength}`;
}

validate(value: string): ValidationResult {
const isValid = !value || value.length <= this.maxLength;
return {
isValid,
message: isValid ? undefined : this.message
};
}
}

class EmailRule implements ValidationRule<string> {
private emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

constructor(private message: string = 'Invalid email format') {}

validate(value: string): ValidationResult {
const isValid = !value || this.emailRegex.test(value);
return {
isValid,
message: isValid ? undefined : this.message
};
}
}

class RangeRule implements ValidationRule<number> {
constructor(
private min: number,
private max: number,
private message?: string
) {
this.message = message || `Value must be between ${min} and ${max}`;
}

validate(value: number): ValidationResult {
const isValid = value >= this.min && value <= this.max;
return {
isValid,
message: isValid ? undefined : this.message
};
}
}

class PatternRule implements ValidationRule<string> {
constructor(
private pattern: RegExp,
private message: string = 'Invalid format'
) {}

validate(value: string): ValidationResult {
const isValid = !value || this.pattern.test(value);
return {
isValid,
message: isValid ? undefined : this.message
};
}
}

// 自定义验证规则
class CustomRule<T> implements ValidationRule<T> {
constructor(
private validator: (value: T) => boolean,
private message: string = 'Validation failed'
) {}

validate(value: T): ValidationResult {
const isValid = this.validator(value);
return {
isValid,
message: isValid ? undefined : this.message
};
}
}

// 验证器类
class Validator<T extends Record<string, any>> {
constructor(private schema: ValidationSchema<T>) {}

validate(data: T): { isValid: boolean; errors: Record<keyof T, string[]> } {
const errors: Record<keyof T, string[]> = {} as any;
let isValid = true;

for (const field in this.schema) {
const rules = this.schema[field];
if (!rules) continue;

const fieldErrors: string[] = [];
const value = data[field];

for (const rule of rules) {
const result = rule.validate(value);
if (!result.isValid && result.message) {
fieldErrors.push(result.message);
isValid = false;
}
}

if (fieldErrors.length > 0) {
errors[field] = fieldErrors;
}
}

return { isValid, errors };
}

validateField(field: keyof T, value: T[keyof T]): ValidationResult {
const rules = this.schema[field];
if (!rules) {
return { isValid: true };
}

for (const rule of rules) {
const result = rule.validate(value);
if (!result.isValid) {
return result;
}
}

return { isValid: true };
}
}

// 使用示例
interface UserRegistration {
username: string;
email: string;
password: string;
age: number;
website?: string;
}

const userValidator = new Validator<UserRegistration>({
username: [
new RequiredRule('Username is required'),
new MinLengthRule(3, 'Username must be at least 3 characters'),
new MaxLengthRule(20, 'Username must not exceed 20 characters'),
new PatternRule(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores')
],
email: [
new RequiredRule('Email is required'),
new EmailRule('Please enter a valid email address')
],
password: [
new RequiredRule('Password is required'),
new MinLengthRule(8, 'Password must be at least 8 characters'),
new PatternRule(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/,
'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character'
)
],
age: [
new RequiredRule('Age is required'),
new RangeRule(13, 120, 'Age must be between 13 and 120')
],
website: [
new PatternRule(/^https?:\/\/.+/, 'Website must be a valid URL')
]
});

// 验证数据
const userData: UserRegistration = {
username: 'john_doe',
email: 'john@example.com',
password: 'SecurePass123!',
age: 25,
website: 'https://johndoe.com'
};

const validationResult = userValidator.validate(userData);

if (validationResult.isValid) {
console.log('Validation passed!');
} else {
console.log('Validation errors:', validationResult.errors);
}

🏗️ 最佳实践与性能优化

1. 代码组织与架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// 项目结构最佳实践
/*
src/
├── types/ # 类型定义
│ ├── api.ts
│ ├── user.ts
│ └── index.ts
├── utils/ # 工具函数
│ ├── validation.ts
│ ├── formatting.ts
│ └── index.ts
├── services/ # 业务服务
│ ├── user.service.ts
│ ├── api.service.ts
│ └── index.ts
├── components/ # 组件
├── hooks/ # 自定义钩子
├── constants/ # 常量
└── tests/ # 测试文件
*/

// 类型安全的配置管理
interface AppConfig {
api: {
baseUrl: string;
timeout: number;
retries: number;
};
features: {
enableLogging: boolean;
enableAnalytics: boolean;
};
ui: {
theme: 'light' | 'dark';
language: string;
};
}

const config: AppConfig = {
api: {
baseUrl: process.env.API_BASE_URL || 'http://localhost:3000',
timeout: 5000,
retries: 3
},
features: {
enableLogging: process.env.NODE_ENV === 'development',
enableAnalytics: process.env.NODE_ENV === 'production'
},
ui: {
theme: 'light',
language: 'en'
}
};

// 错误处理最佳实践
class AppError extends Error {
constructor(
message: string,
public code: string,
public statusCode: number = 500
) {
super(message);
this.name = 'AppError';
}
}

class ValidationError extends AppError {
constructor(message: string, public field: string) {
super(message, 'VALIDATION_ERROR', 400);
this.name = 'ValidationError';
}
}

class NotFoundError extends AppError {
constructor(resource: string) {
super(`${resource} not found`, 'NOT_FOUND', 404);
this.name = 'NotFoundError';
}
}

// 类型安全的事件系统
type EventMap = {
'user:login': { userId: string; timestamp: Date };
'user:logout': { userId: string };
'data:update': { table: string; id: string };
};

class TypedEventEmitter<T extends Record<string, any>> {
private listeners: { [K in keyof T]?: Array<(data: T[K]) => void> } = {};

on<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event]!.push(listener);
}

emit<K extends keyof T>(event: K, data: T[K]): void {
const eventListeners = this.listeners[event];
if (eventListeners) {
eventListeners.forEach(listener => listener(data));
}
}

off<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
const eventListeners = this.listeners[event];
if (eventListeners) {
const index = eventListeners.indexOf(listener);
if (index > -1) {
eventListeners.splice(index, 1);
}
}
}
}

const eventEmitter = new TypedEventEmitter<EventMap>();

// 性能优化技巧
class PerformanceOptimizer {
// 防抖函数
static debounce<T extends (...args: any[]) => any>(
func: T,
delay: number
): (...args: Parameters<T>) => void {
let timeoutId: NodeJS.Timeout;

return (...args: Parameters<T>) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func(...args), delay);
};
}

// 节流函数
static throttle<T extends (...args: any[]) => any>(
func: T,
delay: number
): (...args: Parameters<T>) => void {
let lastCall = 0;

return (...args: Parameters<T>) => {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
func(...args);
}
};
}

// 缓存装饰器
static memoize<T extends (...args: any[]) => any>(func: T): T {
const cache = new Map();

return ((...args: Parameters<T>) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}

const result = func(...args);
cache.set(key, result);
return result;
}) as T;
}
}

2. 测试策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// src/tests/user.service.test.ts
import { UserService } from '../services/user.service';
import { User } from '../types/user';

describe('UserService', () => {
let userService: UserService;

beforeEach(() => {
userService = new UserService('http://localhost:3000');
});

describe('createUser', () => {
it('should create a user with valid data', async () => {
const userData = {
name: 'John Doe',
email: 'john@example.com'
};

const result = await userService.createUser(userData);

expect(result.success).toBe(true);
expect(result.data).toMatchObject(userData);
});

it('should reject invalid email', async () => {
const userData = {
name: 'John Doe',
email: 'invalid-email'
};

const result = await userService.createUser(userData);

expect(result.success).toBe(false);
expect(result.message).toContain('Invalid email format');
});
});
});

// 类型测试
type AssertEqual<T, U> = T extends U ? (U extends T ? true : false) : false;
type AssertTrue<T extends true> = T;

// 测试类型推断
type TestUserType = AssertTrue<AssertEqual<
ReturnType<typeof userService.createUser>,
Promise<ApiResponse<User>>
>>;

🎯 总结

TypeScript作为现代前端开发的核心技术,提供了强大的类型系统和丰富的语言特性。通过本文的实战指南,我们深入学习了:

  1. 类型系统:从基础类型到高级类型,掌握类型安全编程
  2. 面向对象:类、继承、接口等OOP核心概念
  3. 泛型编程:编写可复用、类型安全的代码
  4. 装饰器:元编程和依赖注入的强大工具
  5. 模块化:代码组织和架构设计最佳实践
  6. 实战应用:任务管理和数据验证系统的完整实现

TypeScript不仅提升了代码质量和开发效率,更重要的是为大型项目提供了可维护性保障。在实际开发中,要充分利用TypeScript的类型系统,建立良好的代码规范,注重性能优化和测试覆盖。

随着前端技术的不断发展,TypeScript将继续发挥重要作用。掌握这些核心技能,将为你的前端开发之路奠定坚实基础。