TypeScript 为 JavaScript 带来了静态类型检查,让我们能够在编译时发现错误,提升代码的可维护性和可靠性。
🎯 基础类型使用
基本类型定义
typescript1// 基础类型 2const name: string = "张三"; 3const age: number = 25; 4const isActive: boolean = true; 5 6// 数组类型 7const numbers: number[] = [1, 2, 3]; 8const names: Array<string> = ["Alice", "Bob"]; 9 10// 对象类型 11interface User { 12 id: number; 13 name: string; 14 email?: string; // 可选属性 15 readonly createdAt: Date; // 只读属性 16}
联合类型和交叉类型
typescript1// 联合类型 2type Status = "pending" | "approved" | "rejected"; 3type ID = string | number; 4 5// 交叉类型 6interface Timestamped { 7 createdAt: Date; 8 updatedAt: Date; 9} 10 11type UserWithTimestamp = User & Timestamped;
🔧 高级类型技巧
泛型的使用
typescript1// 泛型函数 2function identity<T>(arg: T): T { 3 return arg; 4} 5 6// 泛型接口 7interface ApiResponse<T> { 8 data: T; 9 status: number; 10 message: string; 11} 12 13// 泛型约束 14interface Lengthwise { 15 length: number; 16} 17 18function loggingIdentity<T extends Lengthwise>(arg: T): T { 19 console.log(arg.length); 20 return arg; 21}
实用工具类型
typescript1interface User { 2 id: number; 3 name: string; 4 email: string; 5 password: string; 6} 7 8// Partial - 使所有属性可选 9type PartialUser = Partial<User>; 10 11// Pick - 选择特定属性 12type PublicUser = Pick<User, 'id' | 'name' | 'email'>; 13 14// Omit - 排除特定属性 15type CreateUser = Omit<User, 'id'>; 16 17// Required - 使所有属性必需 18type RequiredUser = Required<PartialUser>;
📝 最佳实践
1. 严格的类型检查
json1// tsconfig.json 2{ 3 "compilerOptions": { 4 "strict": true, 5 "noImplicitAny": true, 6 "strictNullChecks": true, 7 "strictFunctionTypes": true 8 } 9}
2. 使用类型断言谨慎
typescript1// ❌ 避免使用 any 2const data: any = response.data; 3 4// ❌ 过度使用类型断言 5const user = data as User; 6 7// ✅ 使用类型守卫 8function isUser(obj: any): obj is User { 9 return obj && typeof obj.id === 'number' && typeof obj.name === 'string'; 10} 11 12if (isUser(data)) { 13 // TypeScript 知道这里 data 是 User 类型 14 console.log(data.name); 15}
3. 合理使用枚举
typescript1// ✅ 使用 const 枚举提升性能 2const enum Color { 3 Red = "red", 4 Green = "green", 5 Blue = "blue" 6} 7 8// ✅ 或使用联合类型 9type Color = "red" | "green" | "blue";
🚀 在 React 中使用 TypeScript
组件类型定义
typescript1import React, { FC, ReactNode } from 'react'; 2 3interface ButtonProps { 4 children: ReactNode; 5 variant?: 'primary' | 'secondary'; 6 size?: 'small' | 'medium' | 'large'; 7 onClick?: () => void; 8 disabled?: boolean; 9} 10 11const Button: FC<ButtonProps> = ({ 12 children, 13 variant = 'primary', 14 size = 'medium', 15 onClick, 16 disabled = false 17}) => { 18 return ( 19 <button 20 className={`btn btn-${variant} btn-${size}`} 21 onClick={onClick} 22 disabled={disabled} 23 > 24 {children} 25 </button> 26 ); 27};
Hooks 类型定义
typescript1import { useState, useEffect } from 'react'; 2 3interface User { 4 id: number; 5 name: string; 6 email: string; 7} 8 9// 自定义 Hook 10function useUser(userId: number) { 11 const [user, setUser] = useState<User | null>(null); 12 const [loading, setLoading] = useState(true); 13 const [error, setError] = useState<string | null>(null); 14 15 useEffect(() => { 16 async function fetchUser() { 17 try { 18 setLoading(true); 19 const response = await fetch(`/api/users/${userId}`); 20 if (!response.ok) { 21 throw new Error('Failed to fetch user'); 22 } 23 const userData: User = await response.json(); 24 setUser(userData); 25 } catch (err) { 26 setError(err instanceof Error ? err.message : 'Unknown error'); 27 } finally { 28 setLoading(false); 29 } 30 } 31 32 fetchUser(); 33 }, [userId]); 34 35 return { user, loading, error }; 36}
🛠️ API 层类型安全
定义 API 响应类型
typescript1// API 响应类型 2interface ApiResponse<T> { 3 data: T; 4 status: 'success' | 'error'; 5 message?: string; 6} 7 8interface PaginatedResponse<T> extends ApiResponse<T[]> { 9 pagination: { 10 page: number; 11 limit: number; 12 total: number; 13 totalPages: number; 14 }; 15} 16 17// API 服务 18class UserService { 19 static async getUser(id: number): Promise<User> { 20 const response = await fetch(`/api/users/${id}`); 21 const result: ApiResponse<User> = await response.json(); 22 23 if (result.status === 'error') { 24 throw new Error(result.message || 'Failed to fetch user'); 25 } 26 27 return result.data; 28 } 29 30 static async getUsers(page: number = 1): Promise<PaginatedResponse<User>> { 31 const response = await fetch(`/api/users?page=${page}`); 32 return response.json(); 33 } 34}
⚡ 性能优化
类型导入优化
typescript1// ✅ 使用 type-only 导入 2import type { User } from './types'; 3import type { FC } from 'react'; 4 5// ✅ 分离类型导入和值导入 6import { useState } from 'react'; 7import type { ChangeEvent } from 'react';
避免过度类型化
typescript1// ❌ 过度复杂的类型 2type ComplexType<T, U, V> = T extends U ? V extends string ? T : never : U; 3 4// ✅ 简单明了的类型 5type UserRole = 'admin' | 'user' | 'guest';
🔍 调试和工具
使用 TypeScript 编译器 API
typescript1// 类型检查工具函数 2function assertIsNumber(value: unknown): asserts value is number { 3 if (typeof value !== 'number') { 4 throw new Error('Expected number'); 5 } 6} 7 8// 使用 9function processValue(value: unknown) { 10 assertIsNumber(value); 11 // 这里 TypeScript 知道 value 是 number 类型 12 return value * 2; 13}
配置开发工具
json1// .vscode/settings.json 2{ 3 "typescript.preferences.importModuleSpecifier": "relative", 4 "typescript.suggest.autoImports": true, 5 "typescript.updateImportsOnFileMove.enabled": "always" 6}
📚 总结
TypeScript 最佳实践要点:
- 启用严格模式 - 获得最大的类型安全保障
- 合理使用泛型 - 提升代码复用性
- 避免 any 类型 - 使用类型守卫和断言
- 利用工具类型 - Partial、Pick、Omit 等
- 类型导入优化 - 区分类型和值的导入
- 组件类型定义 - 为 React 组件提供完整的类型支持
掌握这些实践,你就能写出更安全、更可维护的 TypeScript 代码!
评论讨论
使用 GitHub 账号登录即可参与讨论