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

TypeScript中如何约束对象键与value值一致并生成_Option类型

解决TypeScript中对象键与内部value值一致的类型约束问题

需求说明

需要创建TypeScript类型,强制对象的键与其内部value字段的值完全一致,同时通过函数从符合该规则的数据中提取_Option类型的数组。示例数据及函数调用如下:

const data = {
  asd: {
    value: "asd",
    label: "Asd",
    active: false,
  },
  qwe: {
    value: "qwe",
    label: "Qwe",
    active: true,
  },
};

const options = getOptionsFromDetails(data);

遇到的问题

原代码尝试用泛型索引签名约束输入,触发警告:An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.;改用映射类型后又出现值为unknown的问题,原代码如下:

type _Option<TValue extends string> = {
  value: TValue;
  label: string;
};

export const getOptionsFromDetails = <TKey extends string>(
  details: {
    [key: TKey]: {
      value: TKey;
      label: string;
      active: boolean;
    };
  }, 
): _Option<TKey>[] =>

解决方案

使用泛型映射类型实现精准约束,让泛型参数捕获整个输入对象的结构,再通过映射类型强制每个键与对应value值一致:

完整代码实现

type _Option<TValue extends string> = {
  value: TValue;
  label: string;
};

export const getOptionsFromDetails = <T extends Record<string, { value: string; label: string; active: boolean }>>(
  details: { [K in keyof T]: { value: K; label: T[K]['label']; active: T[K]['active'] } }
): _Option<keyof T & string>[] => {
  return Object.values(details).map(({ value, label }) => ({ value, label }));
};

代码说明

  1. 泛型参数T:先捕获输入对象的基础结构,确保每个属性都包含value、label、active字段
  2. 映射类型约束:通过{ [K in keyof T]: ... }强制每个键K对应的value字段类型必须等于K,同时保留label和active的原有类型
  3. 返回值类型:_Option<keyof T & string>[]确保返回的是由对象键作为value的_Option数组,& string过滤掉可能的symbol类型键

验证效果

  • 符合规则的输入会通过类型检查,返回的options类型为_Option<"asd" | "qwe">[]
  • 若键与value不匹配,会直接触发类型错误:
    const invalidData = {
      asd: {
        value: "wrong", // 类型错误:"wrong"不能赋值给类型"asd"
        label: "Asd",
        active: false,
      },
    };
    getOptionsFromDetails(invalidData); // 类型检查失败
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:07:39