You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何对类静态实例实现编译期穷尽匹配?

实现TypeScript编译期穷尽匹配检查的方案

问题根源:直接引用静态值作为类型导致报错

你之前尝试定义type ShapeType = Shape.Circle | Shape.Rectangle | Shape.Triangle时出现语法错误,是因为**Shape.Circle是运行时的值,不是类型**——TypeScript的类型上下文里只能引用类型,要获取静态实例的类型,必须用typeof操作符。

解决步骤

1. 定义静态实例的联合类型

通过typeof Shape[keyof typeof Shape]可以自动获取Shape类所有静态实例的联合类型,不用手动枚举每个静态属性,后续新增实例时也能自动更新类型:

class Shape {
  constructor(
    public readonly angles: number,
    public readonly color: string
  ){}

  static Triangle = new Shape(3, "red");
  static Rectangle = new Shape(4, "blue");
  static Circle = new Shape(0, "green");
}

// 自动生成所有静态Shape实例的联合类型
type ShapeInstance = typeof Shape[keyof typeof Shape];

2. 用never类型实现穷尽检查

定义一个断言函数,配合switch的default分支,只要有未覆盖的实例分支,TypeScript就会在编译期报错:

// 断言函数:仅接收never类型参数,用于触发编译错误
function assertNever(value: never): never {
  throw new Error(`Unexpected shape: ${value}`);
}

function shapeCatchPhrase(shape: ShapeInstance): string {
  switch (shape) {
    case Shape.Triangle:
      return "Three is a magic number";
    case Shape.Rectangle:
      return `Are you a ${shape.color} square?`;
    case Shape.Circle:
      return `Oh! Look at your ${shape.angles} angles!`;
    // 如果新增了Shape静态实例但未添加对应case,这里会触发编译错误
    default:
      return assertNever(shape);
  }
}

3. 进阶:限制外部创建实例(可选)

如果要完全模拟枚举的特性,防止外部通过new Shape()创建非法实例,可以把构造函数设为私有,同时把Shape类型重定义为静态实例的联合类型:

class Shape {
  // 私有构造函数,禁止外部创建实例
  private constructor(
    public readonly angles: number,
    public readonly color: string
  ){}

  static Triangle = new Shape(3, "red");
  static Rectangle = new Shape(4, "blue");
  static Circle = new Shape(0, "green");
}

// 重定义Shape类型为所有静态实例的联合类型
type Shape = typeof Shape[keyof typeof Shape];

// 此时函数参数直接用Shape即可
function shapeCatchPhrase(shape: Shape): string {
  switch (shape) {
    case Shape.Triangle:
      return "Three is a magic number";
    case Shape.Rectangle:
      return `Are you a ${shape.color} square?`;
    case Shape.Circle:
      return `Oh! Look at your ${shape.angles} angles!`;
    default:
      return assertNever(shape);
  }
}

原理说明

  • typeof Shape获取Shape类的静态成员类型(包含Triangle/Rectangle/Circle的键值对类型);
  • keyof typeof Shape获取所有静态成员的键名联合类型("Triangle" | "Rectangle" | "Circle");
  • typeof Shape[keyof typeof Shape]遍历所有静态键,获取对应值的类型,组成最终的实例联合类型;
  • 当switch未覆盖所有联合类型分支时,default分支的shape参数类型会不是never,而assertNever要求参数为never,因此触发编译错误,实现了编译期的穷尽匹配检查。

内容的提问来源于stack exchange,提问作者sge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:27:29