在 TypeScript 中,类型系统非常丰富。为了方便理解和分享,我们可以将 TS 的所有类型划分为以下 8 大类

这是一份“全家谱”,你可以直接放入 PPT:


一、 JavaScript 原始类型 (Primitive Types)

这些是 JS 原生的基础类型,在 TS 中直接对应。

  1. string: 字符串。
  2. number: 数字(含整数、浮点数、NaNInfinity)。
  3. boolean: 布尔值(true / false)。
  4. null: 空值。
  5. undefined: 未定义。
  6. symbol: 独一无二的值。
  7. 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 对比:

特性anyunknown
接受任意值?
赋值给其他类型?
属性/方法检查?✗ 不检查✓ 检查

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)

用于描述复杂的数据结构。

  1. Array<T>T[]: 数组。
  2. Tuple (元组): 固定长度、固定位置类型的数组,如 [string, number]
  3. Interface (接口): 定义对象的结构。
  4. Type Alias (类型别名): 给类型起个新名字。
  5. Enum (枚举): 一组有名字的常量。
  6. Function: 函数类型,可定义入参和返回值类型。

四、 字面量类型 (Literal Types)

类型不仅可以是 string,还可以是具体的值。

  1. 字符串字面量: type Gender = "male" | "female"
  2. 数字字面量: type Dice = 1 | 2 | 3 | 4 | 5 | 6
  3. 布尔字面量: let isTrue: true (只能赋值为 true)。
  4. 模板字符串类型: type HttpRes = `score_${string}` (以 score_ 开头的字符串)。

五、 组合类型 (Composition Types)

将多个类型通过逻辑组合在一起。

  1. Union Types (联合类型): A | B (是 A 或者是 B)。
  2. Intersection Types (交叉类型): A & B (同时具备 A 和 B 的特征)。

六、 进阶逻辑类型 (Advanced/Meta Types)

这些是 TS 强大的”类型编程”能力。

  1. Generic (泛型): 参数化类型,如 T
  2. keyof: 获取对象所有键的联合类型。
  3. typeof: 根据变量的值反推其类型。
  4. Indexed Access Types: 索引访问类型,如 T[K]
  5. Conditional Types (条件类型): T extends U ? X : Y
  6. 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>>; // string
    
  7. Mapped 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 | boolean
    
  • Extract<T, U>: 从 T 中提取可赋值给 U 的类型。
    type T = Extract<string | number | boolean, number | string>;
    // T = string | number
    
  • NonNullable<T>: 排除 nullundefined
    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(类型编程,解决复杂库的定义)。

重点对比这几个:

  • any vs unknown(安全意识)。
  • interface vs type(使用习惯)。
  • void vs never(逻辑严密性)。