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

Typescript如何对嵌套对象按key索引解决类型不兼容问题

问题根因

你遇到的类型报错核心原因是 Object.keys() 方法在TypeScript的默认类型定义中返回的是 string[] 类型,并不会自动推导为目标对象的键字面量联合类型。因此直接用返回的字符串作为索引访问对象属性时,TypeScript无法确认该字符串是目标对象的合法键,就会抛出类型不兼容的错误。

解决方案

方案1:通用工具函数(推荐,不丢失类型精度)

先写一个通用的类型安全的objectKeys工具函数,覆盖默认Object.keys的宽松类型定义:

function objectKeys<T extends object>(obj: T) {
  return Object.keys(obj) as Array<keyof T>;
}

再修改组件代码,替换原有Object.keys调用,补充必要的类型收窄即可:

export const LightTheme = () => (
  <div>
    {objectKeys(light_theme.colors).map((type) => {
      const currentColorGroup = light_theme.colors[type];
      return (
        <TypeContainer key={type}>
          <TypeTitle>{startCase(type)}</TypeTitle>
          <ColorTable>
            <thead>
              <tr>
                <NameTh>Name</NameTh>
                <ValueTh>Value</ValueTh>
              </tr>
            </thead>
            <tbody>
              {objectKeys(currentColorGroup).map((color_name) => (
                <ColorRow key={color_name as string}>
                  <CodeTd>
                    <Code>
                      theme.{type}.{color_name as string}
                    </Code>
                  </CodeTd>
                  <td>
                    <ColorDemoContainer>
                      <ColorBox color={currentColorGroup[color_name as keyof typeof currentColorGroup]} />
                      <ColorValue>
                        {currentColorGroup[color_name as keyof typeof currentColorGroup]}
                      </ColorValue>
                    </ColorDemoContainer>
                  </td>
                </ColorRow>
              ))}
            </tbody>
          </ColorTable>
          <Divider />
        </TypeContainer>
      )
    })}
  </div>
);

方案2:显式定义主题类型(适合宽松校验场景)

如果不需要严格的字面量类型校验,可以提前给主题对象定义宽松的接口类型,让TypeScript直接确认所有层级的属性索引返回的都是颜色字符串,不需要额外的单次断言:

// 定义宽松的主题接口类型
interface ITheme {
  colors: {
    [groupKey: string]: {
      [colorKey: string]: string;
    }
  }
}

// 给light_theme指定类型,原有对象内容不变
export const light_theme: ITheme = Object.freeze({
  colors: {
    brand: {
      primary: COLORS.ROSE_500,
      secondary: COLORS.BLACK_50,
      background: COLORS.WHITE,
    },
    button: {
      action: COLORS.RED_500,
      action_hover: COLORS.RED_600,
      interactive: COLORS.OCEAN_500,
      interactive_hover: COLORS.DARK_OCEAN,
      neutral: COLORS.WHITE,
      disabled: COLORS.GREY_300,
    },
  }
});

使用该方案后,你原有组件代码仅需删除light_theme.colors[type as keyof typeof light_theme.colors]中的类型断言即可正常运行,不会再报类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:54:06