类型分类体系
基础类型
1. 字符串类型(string)
2. 数字类型(number)
3. 布尔类型(boolean)
4. 大整数类型(bigint)
5. 符号类型(symbol)
6. undefined 和 null
7. 字面量类型 限定了值必须是某个具体的字面量,字面量类型包括字符串字面量、数字字面量和布尔字面量。
对象类型
Object 类型表示所有非原始类型(即所有对象)。Object 是所有引用类型的根类型 ,类似于 Java 中的 Object 类。
// Object 类型可以接受任何对象
let obj: Object = { name: "Alice" }; // ✅
obj = [1, 2, 3]; // ✅ 数组是对象
obj = function() {}; // ✅ 函数是对象
obj = new Date(); // ✅ Date 是对象
obj = /regex/; // ✅ 正则表达式是对象
TS新增类型
| 类型 | 核心含义 | 使用场景 | 安全性 |
|---|---|---|---|
| any | 任意类型(关闭类型检查) | 迁移旧代码、第三方库 | ❌ 最不安全 |
| unknown | 未知类型(安全的 any) | 处理未知值、API 响应 | ✅ 安全(需收窄) |
| void | 无返回值 | 函数没有返回值 | ✅ 安全 |
| never | 永不返回 | 异常、无限循环、穷尽检查 | ✅ 最严格 |
| enum | 枚举常量集合 | 定义一组相关常量 | ✅ 安全 |
unknown 是 any 的类型安全版本。 它表示"一个未知的值",但不允许你直接操作它,必须先进行类型收窄(类型守卫)。
unknown 的实际应用:
// 1. API 响应处理
async function fetchData(url: string): Promise<unknown> {
const response = await fetch(url);
const data = await response.json();
return data; // 返回 unknown
}
async function getUser(id: number): Promise<User> {
const data = await fetchData(`/api/users/${id}`);
// 必须验证数据类型
if (typeof data === "object" && data !== null) {
const user = data as any;
if (typeof user.id === "number" && typeof user.name === "string") {
return user as User;
}
}
throw new Error("Invalid user data");
}
// 2. 错误处理(TypeScript 4.0+)
try {
// 某些操作
throw new Error("Something went wrong");
} catch (error) {
// error 类型是 unknown
if (error instanceof Error) {
console.log(error.message);
} else if (typeof error === "string") {
console.log(error);
} else {
console.log("Unknown error");
}
}
// 3. 类型断言(谨慎使用)
let data: unknown = "hello world";
let str: string = data as string; // 断言为 string
console.log(str.length); // 可以
never 表示永远不会发生的值。 它是 TypeScript 类型系统的"底部类型",没有任何值可以赋值给 never 类型。never 是任何类型的子类型
// never 是任何类型的子类型
let str: string = "hello";
// str = neverVar; // 但反过来不行
// never 可以赋值给任何类型
function getNever(): never {
throw new Error("Never");
}
let numberVar: number = getNever(); // ✅ 可以
let stringVar: string = getNever(); // ✅ 可以
let booleanVar: boolean = getNever(); // ✅ 可以
// 但是没有任何类型可以赋值给 never
// let neverVar: never = "hello"; // ❌ 错误
// let neverVar2: never = 42; // ❌ 错误
// let neverVar3: never = undefined; // ❌ 错误
联合类型
表示一个值可以是多种类型中的一种 ,用竖线 | 分隔。它表达了逻辑上的"或"(OR)关系。
联合类型就像是一个"类型开关",变量可以在多个类型之间切换,但一次只能是一种类型。
// 基础语法
type MyType = Type1 | Type2 | Type3;
// 示例:字符串或数字
let id: string | number;
id = "abc123"; // ✅
id = 12345; // ✅
// id = true; // ❌ 错误:boolean 不在联合中
// 基础类型
type ID = string | number;
type Result = string | number | boolean;
type Nullable = string | null | undefined;
// 函数联合类型
type StringProcessor = (input: string) => string;
type NumberProcessor = (input: number) => number;
type Processor = StringProcessor | NumberProcessor;
// 字符串字面量联合
type Direction = "up" | "down" | "left" | "right";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
交叉类型
交叉类型(Intersection Types) 表示一个值同时具有多种类型的所有成员 ,用与符号 & 连接。它表达了逻辑上的"与"(AND)关系。
交叉类型就像是"类型合并器",把多个类型的属性全部组合 到一个新类型中。它可以被理解为所有类型的交集。
如果交叉的两个对象属性如果存在相同但是类型不同 就会冲突报错。
// 基础语法
type Combined = Type1 & Type2 & Type3;
// 示例:合并两个接口
interface Person {
name: string;
age: number;
}
interface Employee {
employeeId: string;
department: string;
}
// 交叉类型:同时具有 Person 和 Employee 的所有属性
type EmployeePerson = Person & Employee;
const worker: EmployeePerson = {
name: "Alice", // 来自 Person
age: 30, // 来自 Person
employeeId: "E001", // 来自 Employee
department: "Engineering" // 来自 Employee
};
TypeScript 中 Interface 和 Class 的区别详解
| 特性 | Interface(接口) | Class(类) |
|---|---|---|
| 本质 | 纯类型定义 | 既是类型又是值 |
| 编译后 | 完全消失 | 变成 JavaScript 代码 |
| 作用 | 描述对象结构 | 创建对象蓝图 |
| 实例化 | ❌ 不能 new | ✅ 可以 new |
| 方法实现 | ❌ 只有声明 | ✅ 可以包含实现 |
| 访问修饰符 | ❌ 不支持 | ✅ public/private/protected |
| 继承 | ✅ 可以继承多个 | ✅ 只能单继承 |