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

数组中不同关联泛型类型的类型安全实现问题

解决方案:用泛型约束确保操作类型与参数的关联

要解决这个问题,核心是让TypeScript严格检查数组中每个操作的type和operation类型是否匹配,避免联合类型数组导致的类型放宽问题。可以通过泛型类/泛型构造函数来实现:

方法一:泛型类

将CompoundOperation定义为泛型类,泛型参数约束为合法的操作数组,确保每个元素的类型关联不丢失:

type OperationTypes = "move" | "rotate" | "rename";

type OperationsMap = {
  move: [number, number];
  rotate: number;
  rename: string;
};

type OperationRaw<K extends OperationTypes> = {
  type: K;
  operation: OperationsMap[K];
};

// 泛型类,T约束为只读的合法操作数组
export class CompoundOperation<T extends readonly OperationRaw<OperationTypes>[]> {
  _operations: T;

  constructor(operations: T) {
    this._operations = operations;
  }
}

// ✅ 合法示例:类型检查通过
new CompoundOperation([
  { type: "move", operation: [10, 20] },
  { type: "rotate", operation: 90 },
  { type: "rename", operation: "new-file" }
]);

// ❌ 非法示例:类型错误(operation类型与move不匹配),符合预期
new CompoundOperation([{ type: "move", operation: "Default" }]);

方法二:泛型构造函数(非泛型类)

如果不需要类本身保留数组的具体类型信息,也可以仅在构造函数中使用泛型约束:

export class CompoundOperation {
  _operations: readonly OperationRaw<OperationTypes>[];

  // 构造函数泛型约束传入的数组每个元素都是合法的OperationRaw
  constructor<T extends readonly OperationRaw<OperationTypes>[]>(operations: T) {
    this._operations = operations;
  }
}

原理说明

原来的OperationRaw<OperationTypes>[]是联合类型数组,在部分宽松检查模式下,TypeScript无法保证单个元素内部type与operation的严格匹配。通过泛型约束,我们强制要求传入的数组每个元素都必须是某个具体的OperationRaw<K>(比如OperationRaw<"move">或OperationRaw<"rotate">),从而确保每个操作的类型关联不丢失。

内容的提问来源于stack exchange,提问作者Jurek O.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:22:46