在 TypeScript 中,类型系统非常丰富。为了方便理解和分享,我们可以将 TS 的所有类型划分为以下 8 大类。
这是一份“全家谱”,你可以直接放入 PPT:
一、 JavaScript 原始类型 (Primitive Types)
这些是 JS 原生的基础类型,在 TS 中直接对应。
string: 字符串。number: 数字(含整数、浮点数、NaN、Infinity)。boolean: 布尔值(true/false)。null: 空值。undefined: 未定义。symbol: 独一无二的值。bigint: 任意精度的整数(如100n)。
二、 TypeScript 特有基础类型 (TS Specific Types)
TS 为了弥补 JS 的类型缺失而引入的特殊类型。
1. any - 关闭类型检查
表面上是”任意类型”,本质是跳过所有类型检查。就像告诉编译器”别管我,我知道自己在做什么”。
let value: any = "hello";
// ✓ 编译器都不检查,随便你怎么操作
value.foo.bar; // 运行时可能报错,但编译通过
value(); // 把字符串当函数调用,编译通过
value[0][1][2]; // 随意访问,编译通过
value.toFixed(); // 字符串没有这个方法,编译也通过
// 可以赋值给任何类型
let num: number = value; // ✓ 编译通过
2. unknown - 安全的任意类型
表示”任意类型”,但保持类型检查。必须先收窄类型才能使用。
let value: unknown = "hello";
value.toUpperCase(); // ✗ 编译报错:对象类型为 unknown
// 必须先进行类型检查
if (typeof value === "string") {
value.toUpperCase(); // ✓ 类型收窄后才能用
}
any vs unknown 对比:
| 特性 | any | unknown |
|---|---|---|
| 接受任意值? | ✓ | ✓ |
| 赋值给其他类型? | ✓ | ✗ |
| 属性/方法检查? | ✗ 不检查 | ✓ 检查 |
3. void - 无返回值
表示函数没有返回值。
function log(message: string): void {
console.log(message);
// 没有 return 或 return undefined
}
4. never - 永不存在的值
表示永远不可能存在的类型,用于:
- 总是抛出异常的函数
- 永远返回不了的函数(死循环)
function throwError(message: string): never {
throw new Error(message); // 永远不会返回
}
function infiniteLoop(): never {
while (true) {} // 永远不会返回
}
// 类型收窄中的 never
function getValue(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase();
}
// 这里 value 的类型是 never(因为所有可能都已处理)
return value * 2;
}
5. object - 非原始类型
代表任何非原始类型(即非 number, string, boolean, symbol, bigint, null, undefined)的值。
function process(obj: object) {
console.log(Object.keys(obj)); // ✓ 可以用对象方法
}
process({ name: "test" }); // ✓
process([1, 2, 3]); // ✓(数组也是对象)
process("string"); // ✗ 原始类型不行
注意:更推荐用
Record<string, unknown>或接口类型代替object。
三、 结构化类型 (Structured Types)
用于描述复杂的数据结构。
Array<T>或T[]: 数组。Tuple(元组): 固定长度、固定位置类型的数组,如[string, number]。Interface(接口): 定义对象的结构。Type Alias(类型别名): 给类型起个新名字。Enum(枚举): 一组有名字的常量。Function: 函数类型,可定义入参和返回值类型。
四、 字面量类型 (Literal Types)
类型不仅可以是 string,还可以是具体的值。
- 字符串字面量:
type Gender = "male" | "female"。 - 数字字面量:
type Dice = 1 | 2 | 3 | 4 | 5 | 6。 - 布尔字面量:
let isTrue: true(只能赋值为 true)。 - 模板字符串类型:
type HttpRes = `score_${string}`(以 score_ 开头的字符串)。
五、 组合类型 (Composition Types)
将多个类型通过逻辑组合在一起。
Union Types(联合类型):A | B(是 A 或者是 B)。Intersection Types(交叉类型):A & B(同时具备 A 和 B 的特征)。
六、 进阶逻辑类型 (Advanced/Meta Types)
这些是 TS 强大的”类型编程”能力。
Generic(泛型): 参数化类型,如T。keyof: 获取对象所有键的联合类型。typeof: 根据变量的值反推其类型。Indexed Access Types: 索引访问类型,如T[K]。Conditional Types(条件类型):T extends U ? X : Y。infer(类型推断): 在条件类型中推断类型,常用于提取函数的返回值、参数等。// 提取函数返回值类型(ReturnType 的简化版) type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never; function foo() { return "hello"; } type R = MyReturnType<typeof foo>; // "hello" // 提取 Promise 内部的类型 type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; type T = UnwrapPromisePromise<string>>; // stringMapped Types(映射类型): 从旧类型映射出新类型,如{ [P in K]: T[P] }。
七、 内置工具类型 (Built-in Utility Types)
TS 官方预设的快捷工具,用于处理接口/对象。
属性修饰类:
Partial<T>: 将所有属性变为可选。interface User { name: string; age: number; } type PartialUser = Partial<User>; // { name?: string; age?: number; }Required<T>: 将所有属性变为必选。interface PartialUser { name?: string; age?: number; } type FullUser = Required<PartialUser>; // { name: string; age: number; }Readonly<T>: 将所有属性变为只读。interface User { name: string; } type ReadonlyUser = Readonly<User>; // { readonly name: string; }
结构操作类:
Pick<T, K>: 挑选出一部分属性。interface User { id: number; name: string; age: number; } type UserBasic = Pick<User, "id" | "name">; // { id: number; name: string; }Omit<T, K>: 排除掉一部分属性。interface User { id: number; name: string; password: string; } type PublicUser = Omit<User, "password">; // { id: number; name: string; }Record<K, T>: 生成键值对类型。type PageInfo = Record<string, { title: string; url: string }>; // 等价于 { [key: string]: { title: string; url: string } }
类型过滤类:
Exclude<T, U>: 从 T 中排除可赋值给 U 的类型。type T = Exclude<string | number | boolean, number>; // T = string | booleanExtract<T, U>: 从 T 中提取可赋值给 U 的类型。type T = Extract<string | number | boolean, number | string>; // T = string | numberNonNullable<T>: 排除null和undefined。type T = NonNullable<string | null | undefined>; // T = string
函数类型操作类:
ReturnType<T>: 获取函数返回值的类型。function foo() { return { x: 10, y: 20 }; } type R = ReturnType<typeof foo>; // { x: number; y: number; }Parameters<T>: 获取函数参数类型的元组。function foo(x: string, y: number) { } type P = Parameters<typeof foo>; // [x: string, y: number]ConstructorParameters<T>: 获取构造函数参数类型。class Person { constructor(name: string, age: number) {} } type P = ConstructorParameters<typeof Person>; // [name: string, age: number]InstanceType<T>: 获取构造函数返回的实例类型。class Person { name: string; } type I = InstanceType<typeof Person>; // Person
字符串操作类:
Uppercase,Lowercase,Capitalize,Uncapitalize: 字符串大小写转换。type T1 = Uppercase<"hello">; // "HELLO" type T2 = Lowercase<"HELLO">; // "hello" type T3 = Capitalize<"hello">; // "Hello" type T4 = Uncapitalize<"Hello">; // "hello"
this 类型操作:
ThisParameterType<T>: 提取函数的 this 类型。OmitThisParameter<T>: 移除函数的 this 类型。function toHex(this: Number) { return this.toString(16); } type T = ThisParameterType<typeof toHex>; // Number type T2 = OmitThisParameter<typeof toHex>; // () => string
八、 类型安全增强 (Type Safety Enhancements)
运行时和编译时的类型安全保障。
1. 类型守卫 (Type Guards)
在运行时检查类型,帮助 TS 缩小类型范围。
-
typeof守卫: 检查原始类型。function printLength(value: string | number) { if (typeof value === "string") { console.log(value.length); // 这里 TS 知道 value 是 string } else { console.log(value.toFixed(2)); // 这里 TS 知道 value 是 number } } -
instanceof守卫: 检查类实例。class Dog { bark() {} } class Cat { meow() {} } function makeSound(animal: Dog | Cat) { if (animal instanceof Dog) { animal.bark(); // animal 是 Dog } else { animal.meow(); // animal 是 Cat } } -
in守卫: 检查属性是否存在。interface Bird { fly(): void; layEggs(): void; } interface Fish { swim(): void; layEggs(): void; } function move(animal: Bird | Fish) { if ("fly" in animal) { animal.fly(); // animal 是 Bird } else { animal.swim(); // animal 是 Fish } } -
自定义类型守卫 (
is关键字): 使用谓词函数。function isString(value: unknown): value is string { return typeof value === "string"; } function process(value: unknown) { if (isString(value)) { console.log(value.toUpperCase()); // value 被识别为 string } } -
判别联合 (Discriminated Unions): 通过共同字面量属性区分类型。
interface Circle { kind: "circle"; radius: number; } interface Square { kind: "square"; side: number; } function getArea(shape: Circle | Square) { if (shape.kind === "circle") { return Math.PI * shape.radius ** 2; // shape 是 Circle } return shape.side ** 2; // shape 是 Square }
2. 类型断言 (Type Assertions)
告诉编译器”相信我,我知道这是什么类型”。
-
as语法 (推荐)。const value = "hello" as string; const input = document.querySelector("input") as HTMLInputElement; -
<>语法 (JSX 中不可用)。const value = <string>"hello"; -
非空断言
!: 断言值不为 null/undefined。function greet(name: string | null) { console.log(name!.toUpperCase()); // 确信 name 不为 null } -
双重断言: 当类型完全不兼容时(慎用)。
const value = "hello" as unknown as number; // 强制转换
3. 类型收窄 (Type Narrowing)
TS 自动缩小类型的各种场景。
- 真值检查:
if (value)自动排除null,undefined,0,"",false - 等值检查:
===,!== - 逻辑运算:
&&,||,??
总结分享建议:
在 PPT 里可以画一张“金字塔图”:
- 底层:
string,number等原始类型(最简单)。 - 中层:
Interface,Union,Enum(日常业务最常用)。 - 顶层:
Conditional Types,Mapped Types(类型编程,解决复杂库的定义)。
重点对比这几个:
anyvsunknown(安全意识)。interfacevstype(使用习惯)。voidvsnever(逻辑严密性)。