前端开发

TypeScript 基础概念详解

深入了解 TypeScript 的基础概念,包括类型注解、接口、泛型等核心特性,为初学者提供完整的入门指导。

Zee
2024-01-15
12分钟
3 个标签
TypeScriptJavaScript类型系统

TypeScript 基础概念详解

TypeScript 是 JavaScript 的超集,为 JavaScript 添加了静态类型检查。本文将详细介绍 TypeScript 的核心概念。

为什么选择 TypeScript?

1. 类型安全

TypeScript 在编译时就能发现类型错误,而不是在运行时:

typescript
// JavaScript - 运行时才会发现错误 function greet(name) { return "Hello, " + name.toUpperCase(); } greet(123); // 运行时错误 // TypeScript - 编译时就能发现错误 function greet(name: string): string { return "Hello, " + name.toUpperCase(); } greet(123); // 编译时错误:Argument of type 'number' is not assignable to parameter of type 'string'

2. 更好的开发体验

  • 智能代码补全
  • 重构支持
  • 导航和搜索

基础类型

原始类型

typescript
let name: string = "张三"; let age: number = 25; let isStudent: boolean = true; let nothing: null = null; let notDefined: undefined = undefined;

数组类型

typescript
// 两种写法都可以 let numbers: number[] = [1, 2, 3]; let strings: Array<string> = ["a", "b", "c"];

对象类型

typescript
// 直接定义 let person: { name: string; age: number } = { name: "李四", age: 30 }; // 使用接口定义 interface Person { name: string; age: number; email?: string; // 可选属性 } let user: Person = { name: "王五", age: 28 };

接口 (Interface)

接口是 TypeScript 的核心概念之一,用于定义对象的结构:

typescript
interface BlogPost { id: number; title: string; content: string; author: string; publishDate: Date; tags: string[]; isPublished: boolean; } // 使用接口 const post: BlogPost = { id: 1, title: "我的第一篇博客", content: "这是文章内容...", author: "张三", publishDate: new Date(), tags: ["TypeScript", "前端"], isPublished: true };

接口继承

typescript
interface Animal { name: string; age: number; } interface Dog extends Animal { breed: string; bark(): void; } const myDog: Dog = { name: "小白", age: 3, breed: "金毛", bark() { console.log("汪汪汪!"); } };

函数类型

函数参数和返回值类型

typescript
// 基础函数类型 function add(a: number, b: number): number { return a + b; } // 箭头函数 const multiply = (a: number, b: number): number => a * b; // 可选参数 function greet(name: string, title?: string): string { if (title) { return `Hello, ${title} ${name}`; } return `Hello, ${name}`; } // 默认参数 function createUser(name: string, role: string = "user"): object { return { name, role }; }

函数重载

typescript
function format(value: string): string; function format(value: number): string; function format(value: string | number): string { if (typeof value === "string") { return value.toUpperCase(); } return value.toFixed(2); }

泛型 (Generics)

泛型让我们能够创建可重用的组件:

typescript
// 基础泛型函数 function identity<T>(arg: T): T { return arg; } let output1 = identity<string>("hello"); // string let output2 = identity<number>(42); // number // 泛型接口 interface ApiResponse<T> { data: T; status: number; message: string; } // 使用泛型接口 const userResponse: ApiResponse<Person> = { data: { name: "张三", age: 25 }, status: 200, message: "success" }; const postResponse: ApiResponse<BlogPost[]> = { data: [post], status: 200, message: "success" };

泛型约束

typescript
interface Lengthwise { length: number; } function logLength<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; } logLength("hello"); // ✓ 字符串有 length 属性 logLength([1, 2, 3]); // ✓ 数组有 length 属性 logLength(123); // ✗ 数字没有 length 属性

联合类型和交叉类型

联合类型 (Union Types)

typescript
type StringOrNumber = string | number; type Status = "pending" | "approved" | "rejected"; function formatId(id: StringOrNumber): string { if (typeof id === "string") { return id.toUpperCase(); } return id.toString(); } let currentStatus: Status = "pending"; // ✓ // currentStatus = "invalid"; // ✗ 不是有效的状态值

交叉类型 (Intersection Types)

typescript
interface Colorful { color: string; } interface Circle { radius: number; } type ColorfulCircle = Colorful & Circle; const cc: ColorfulCircle = { color: "red", radius: 42 };

实用工具类型

TypeScript 提供了许多内置的工具类型:

typescript
interface User { id: number; name: string; email: string; age: number; } // Pick - 选择部分属性 type UserPreview = Pick<User, 'id' | 'name'>; // Omit - 排除部分属性 type CreateUser = Omit<User, 'id'>; // Partial - 所有属性变为可选 type UpdateUser = Partial<User>; // Required - 所有属性变为必需 type CompleteUser = Required<User>; // Record - 创建键值对类型 type UserRoles = Record<string, string>; const roles: UserRoles = { admin: "管理员", user: "普通用户", guest: "访客" };

类型断言

有时我们比 TypeScript 更了解某个值的类型:

typescript
// 类型断言的两种语法 let someValue: unknown = "this is a string"; let strLength1: number = (someValue as string).length; let strLength2: number = (<string>someValue).length; // 在 JSX 中只能使用 as 语法 // let strLength = (<string>someValue).length; // 会与 JSX 语法冲突

最佳实践

1. 优先使用类型推断

typescript
// 好的做法 let name = "张三"; // TypeScript 自动推断为 string let numbers = [1, 2, 3]; // 推断为 number[] // 不必要的类型注解 let name: string = "张三"; let numbers: number[] = [1, 2, 3];

2. 使用严格模式

tsconfig.json 中启用严格模式:

json
{ "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true } }

3. 为函数参数和返回值添加类型

typescript
// 清晰的函数签名 function processUser(user: User): UserPreview { return { id: user.id, name: user.name }; }

总结

TypeScript 为 JavaScript 开发带来了以下优势:

  1. 类型安全:编译时捕获错误
  2. 更好的 IDE 支持:代码补全、重构、导航
  3. 代码自文档化:类型即文档
  4. 重构信心:大规模重构更安全
  5. 团队协作:接口定义让团队协作更顺畅

掌握了这些基础概念,你就能够开始使用 TypeScript 开发更健壮的应用了。在实际项目中,建议从简单的类型注解开始,逐步学习更高级的特性。