TypeScript 的核心价值在于其强大的类型系统,它能够显著提高代码的可靠性、可维护性和开发体验。本文将全面解析 TypeScript 中的各种类型,帮助您构建更加健壮的应用程序。
TypeScript 类型系统概览
TypeScript 的类型系统可以归纳为以下几个主要类别:
| 类型类别 | 主要类型 | 特点 |
|---|---|---|
| 基本类型 | string, number, boolean 等 | JavaScript 的基础值类型 |
| 复合类型 | 数组、元组、对象、函数 | 由基础类型组合而成 |
| 特殊类型 | any, unknown, void, never | 特殊场景使用的类型 |
| 结构类型 | 接口、类、字面量 | 描述对象结构 |
| 高级类型 | 联合、交叉、条件类型等 | 提供高级类型操作 |
现在让我们深入探索每一类类型。
一、基本原始类型 (Primitive Types)
这些类型对应 JavaScript 的基本值类型:
// 字符串类型
let name: string = "Alice";
let greeting: string = `Hello, ${name}!`;
// 数字类型 (包含整数和浮点数)
let age: number = 30;
let temperature: number = 24.5;
// 布尔类型
let isActive: boolean = true;
let hasPermission: boolean = false;
// null 和 undefined 类型
let emptyValue: null = null;
let notSet: undefined = undefined;
// Symbol 类型 (ES2015+)
const uniqueID: symbol = Symbol("uid");
特殊基本类型:bigint
处理超出 Number 安全整数限制的大整数:
// bigint 类型 (ES2020+)
const hugeNumber: bigint = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1);
二、数组与元组类型 (Collection Types)
数组类型 (Arrays)
TypeScript 提供了多种声明数组类型的语法:
let numbers: number[] = [1, 2, 3]; // 推荐语法
let colors: Array<string> = ["red", "green", "blue"]; // 泛型语法
// 只读数组
const readonlyColors: ReadonlyArray<string> = ["red", "blue"];
// readonlyColors.push("green"); // 错误:只读数组无法修改
元组类型 (Tuples)
固定长度和类型的数组:
// 基本元组
let userInfo: [string, number] = ["Alice", 30];
// 元组解构
const [name, age] = userInfo;
// 可选元素的元组
type HttpResponse = [
number, // 状态码
string, // 状态消息
object?, // 可选的数据对象 (TypeScript 4.0+)
...string[] // 可变的附加信息
];
const response: HttpResponse = [200, "OK", { data: "success" }, "additional info"];
常量元组 (as const)
使用 as const 创建不可变元组:
const rgb = ["red", "green", "blue"] as const;
// rgb[0] = "yellow"; // 错误:只读属性
三、对象类型与接口 (Object Types & Interfaces)
对象类型注解
// 内联对象类型
let user: { name: string; age: number; isAdmin?: boolean } = {
name: "Bob",
age: 25
};
接口 - 定义对象结构
// 基本接口
interface User {
id: number;
name: string;
email: string;
age?: number; // 可选属性
readonly joinDate: Date; // 只读属性
}
// 使用接口
const newUser: User = {
id: 1,
name: "Alice",
email: "alice@example.com",
joinDate: new Date()
};
// 接口继承
interface Admin extends User {
permissions: string[];
deleteUser(): void;
}
索引签名
处理动态键名:
interface DynamicObject {
[key: string]: number;
}
const scores: DynamicObject = {
math: 95,
science: 90
};
四、函数类型 (Function Types)
函数声明和参数类型
// 具名函数
function calc(a: number, b: number): number {
return a + b;
}
// 箭头函数
const multiply: (x: number, y: number) => number = (x, y) => x * y;
// 可选参数和默认值
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
// 剩余参数
function log(...args: (string | number)[]): void {
console.log(args.join(", "));
}
函数接口
interface SearchFunction {
(source: string, keyword: string): boolean;
}
const search: SearchFunction = (src, key) => src.includes(key);
五、联合与交叉类型 (Union & Intersection Types)
联合类型 (|)
表示多种可能的类型:
type ID = string | number;
function printId(id: ID) {
if (typeof id === "string") {
console.log(`ID: ${id.toUpperCase()}`);
} else {
console.log(`ID: ${id.toFixed(2)}`);
}
}
交叉类型 (&)
组合多个类型:
interface Name {
name: string;
}
interface Contact {
email: string;
phone: string;
}
type Employee = Name & Contact;
const alice: Employee = {
name: "Alice",
email: "alice@company.com",
phone: "123-456-7890"
};
六、字面量类型 (Literal Types)
固定值的类型:
// 字符串字面量类型
type Direction = "north" | "south" | "east" | "west";
const move: Direction = "north";
// 数字字面量类型
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
const roll: DiceRoll = 4;
// 布尔字面量类型
type IsTrue = true;
const value: IsTrue = true;
七、枚举类型 (Enums)
定义命名常量集合:
// 数字枚举
enum UserRole {
Guest, // 0
Member, // 1
Admin, // 2
SuperAdmin // 3
}
// 字符串枚举
enum HttpMethod {
GET = "GET",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE"
}
// 常量枚举(编译时内联)
const enum LogLevel {
Error,
Warn,
Info,
Debug
}
八、特殊类型
any:最灵活的类型(谨慎使用)
let flexible: any = "I can be anything!";
flexible = 42; // 允许
flexible = true; // 允许
unknown:类型安全的 any 替代
let input: unknown = getUserInput(); // 来源未知的值
if (typeof input === "string") {
console.log(input.toUpperCase()); // 类型已收窄
}
void 和 never
// void - 表示没有返回值的函数
function logMessage(): void {
console.log("This returns nothing");
}
// never - 表示永远不会返回的函数
function error(message: string): never {
throw new Error(message);
}
// never 也用于处理不可能的情况
type Possible = string | number;
function check(value: Possible) {
if (typeof value === "string") {
// 处理字符串
} else if (typeof value === "number") {
// 处理数字
} else {
// 这里 value 的类型是 never
// 确保处理了所有可能的情况
}
}
九、类型别名 (Type Aliases)
创建自定义类型名称:
// 基本类型别名
type Point = {
x: number;
y: number;
};
// 函数类型别名
type Calculator = (a: number, b: number) => number;
// 泛型类型别名
type Pair<T> = [T, T];
const numbers: Pair<number> = [1, 2];
接口 vs 类型别名
| 特性 | 接口 (interface) | 类型别名 (type) |
|---|---|---|
| 扩展方式 | extends | 交叉类型 (&) |
| 合并声明 | ✅ 支持接口合并 | ❌ 不支持 |
| 实现类 | ✅ 可用于类实现 | ❌ 不能实现 |
| 复杂类型 | ❌ 有限支持 | ✅ 支持联合、元组等 |
| 泛型 | ✅ 支持 | ✅ 支持 |
| 描述对象 | ✅ 主要用途 | ✅ 可以描述 |
| 描述其他类型 | ❌ 不支持 | ✅ 支持各种类型 |
十、高级类型
条件类型 (Conditional Types)
根据条件选择类型:
type NonNullable<T> = T extends null | undefined ? never : T;
// 使用示例
type ValidString = NonNullable<string | null>; // string
映射类型 (Mapped Types)
转换现有类型:
// 所有属性变为可选
type Partial<T> = {
[P in keyof T]?: T[P];
};
// 所有属性变为只读
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
模板字面量类型 (Template Literal Types)
type Color = "red" | "blue" | "green";
type Size = "sm" | "md" | "lg";
type ButtonClass = `btn-${Color}-${Size}`;
// "btn-red-sm" | "btn-red-md" | "btn-red-lg" | "btn-blue-sm" | ...
索引访问和键类型
interface Person {
name: string;
age: number;
address: {
city: string;
zipCode: string;
};
}
type PersonKeys = keyof Person; // "name" | "age" | "address"
type AgeType = Person["age"]; // number
type CityType = Person["address"]["city"]; // string
类型实践:最佳实践与建议
-
避免过度使用
any:优先使用unknown和类型断言替代 -
利用类型推断:让 TypeScript 自动推断类型,减少手动注解
-
使用
const断言:创建不可变值和字面量类型const colors = ["red", "green"] as const; -
优先选择联合类型而非枚举:更符合 TypeScript 的声明式风格
// 优于枚举 const UserRole = { Admin: "admin", User: "user" } as const; type UserRole = typeof UserRole[keyof typeof UserRole]; -
使用严格模式:开启
strict编译器标志以获得更强的类型检查
拥抱类型的力量
TypeScript 的类型系统提供了构建可靠应用程序的坚实基础:
- 开发阶段:通过自动补全和实时错误检查提升开发效率
- 重构阶段:安全地进行大型重构,避免引入错误
- 调试阶段:减少运行时错误,提高代码可靠性
- 协作阶段:清晰表达代码意图,提高团队协作效率
“类型不是约束,而是表达意图的方式 - 它们使代码更具可读性、可维护性和自文档化。” - TypeScript 理念
开始使用这些类型技术,您将体验到更少的错误、更少的调试时间和更愉悦的开发体验。随着 TypeScript 的发展,类型系统也在不断进化,持续关注新特性将使您的代码保持前沿!