You need to enable JavaScript to run this app. TypeScript中如何定义基于类型自身键的索引签名
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何定义基于类型自身键的索引签名

问题根因

你遇到的类型报错,是自定义全局开放索引签名导致的推导偏差:

  • 你在类型里写的[index: string]: object | TypeExperience属于无约束的开放索引签名,TypeScript识别到这个签名后,会把所有通过变量索引访问的返回值,统一推导为索引签名声明的联合类型object | TypeExperience,不会结合你单独显式定义的name、server、site字段的具体结构做类型窄化。
  • 哪怕你的实际对象里每个字段都带title属性,TS在变量索引的场景下,因为无法提前知道运行时会取到哪个具体键,没法确认当前返回值上存在title,最终抛出“属性不存在”的报错。
正确实现路径

你想要的“索引取值严格匹配类型自身已定义的键、索引访问时能拿到对应键的具体结构类型”,完全不需要依赖无约束的字符串索引签名,按以下步骤调整即可:

  • 移除类型定义里多余的全局开放索引签名
    先把TypeAbCreationModal还原为字段明确的结构,不要强行加通用索引约束:
    export type TypeAbCreationModal = {
      name: {
        title: string;
        placeholder: string;
      };
      server: {
        title: string;
        tooltip: string;
      };
      site: {
        title: string;
        placeholder: string;
        placeholderSearch: string;
      };
      // 如果确实需要支持部分自定义动态键,就针对性写带格式约束的索引签名,不要写无约束的string索引
      [dynamicKey: `custom_${string}`]: TypeExperience;
    };
    
  • 将索引用的TypeExperience类型绑定到目标类型的键集合上
    借助TypeScript内置的keyof规则,把做索引用的类型约束为TypeAbCreationModal所有合法键的集合,从根源上避免非法索引访问:
    // 自动推导TypeExperience的取值范围为 "name" | "server" | "site" | 所有custom_开头的动态键
    type TypeExperience = keyof TypeAbCreationModal;
    
  • 调整完成后,形如myObj[someIndex].title的代码就可以通过类型校验
    TypeScript会根据传入的具体键值,自动匹配对应字段的结构类型,只要所有合法键对应的字段都包含title属性,就不会触发属性不存在的报错。
边界场景处理

如果你的TypeExperience是提前独立定义的字面量联合,不需要从TypeAbCreationModal推导取值范围,可以加一层静态校验,避免两边键集合不一致导致的类型不匹配:

// 提前独立定义的索引类型
type TypeExperience = "name" | "server" | "site";

// 静态校验:如果TypeExperience里存在不属于TypeAbCreationModal的键,这里就会抛出类型报错
type KeyMatchCheck = TypeExperience extends keyof TypeAbCreationModal ? true : never;
const matchResult: KeyMatchCheck = true;

注意:无约束的[index: string]: X索引签名,仅适合需要支持任意动态字符串键、且所有键的取值都满足X类型的场景,不适合用来实现基于固定键集合的索引访问逻辑。

内容的提问来源于stack exchange,提问作者Slava.In

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 11:45:10