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

如何让TypeScript对象的映射键仅存在于自身数组元素中?

问题解答

是否需要自引用类型?

是的,要实现mySpecificMapping的键只能是myArray中存在的枚举值这一约束,必须通过泛型结合自引用式的类型约束来实现。原代码里的普通接口无法让两个属性的类型动态关联,必须借助泛型建立myArray和mySpecificMapping的依赖关系。

实现方案

我们可以定义泛型类型来关联两个属性的取值范围,让mySpecificMapping的键只能是myArray中出现的枚举值:

enum ENUM_A { 
  ONE="ONE",
  TWO="TWO",
  THREE="THREE",
  FOUR="FOUR"
}

// 泛型类型,T 代表 myArray 中允许的枚举值集合
type TYPE_A<T extends ENUM_A> = {
  myArray: T[],
  mySpecificMapping: {
    [K in T]?: boolean
  }
}

// 手动指定泛型参数,约束 mySpecificMapping 的键只能是 ONE/THREE
const myObject: TYPE_A<ENUM_A.ONE | ENUM_A.THREE> = {
  myArray: [ENUM_A.ONE, ENUM_A.THREE],
  mySpecificMapping: {
    [ENUM_A.ONE]: true,
    // 取消下面这行注释会触发 TypeScript 错误
    // [ENUM_A.TWO]: true,
    [ENUM_A.THREE]: true,
    // 取消下面这行注释会触发 TypeScript 错误
    // [ENUM_A.FOUR]: true,
  }
}

// 用辅助函数自动推导泛型参数,无需手动指定
const createTYPE_A = <T extends ENUM_A>(obj: TYPE_A<T>) => obj;

// 自动推导 T 为 ENUM_A.ONE | ENUM_A.THREE,非法键会直接报错
const myObject2 = createTYPE_A({
  myArray: [ENUM_A.ONE, ENUM_A.THREE],
  mySpecificMapping: {
    [ENUM_A.ONE]: true,
    // [ENUM_A.TWO]: true, // 此处会立即触发类型错误
    [ENUM_A.THREE]: true,
    // [ENUM_A.FOUR]: true, // 此处会立即触发类型错误
  }
});

原代码的问题

原接口TYPE_A中,myArray是任意ENUM_A元素组成的数组,mySpecificMapping允许所有ENUM_A成员作为键,两者没有类型关联。所以即使mySpecificMapping包含myArray中没有的键,TypeScript也不会判定为错误。

泛型约束的作用

这里的泛型T相当于把myArray的实际元素类型提取出来,再用这个类型去限制mySpecificMapping的键范围,本质上是让类型的两个属性形成自引用依赖——mySpecificMapping的合法键由myArray的取值决定,这种动态关联只有泛型能实现,普通接口无法做到。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:22:14