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

TypeScript报错:类型'string'不存在属性'title',索引签名含该属性

TypeScript索引签名类型收窄无效问题解决

你的问题核心在于:payload类型同时包含固定属性name和索引签名[id: string]: string | { title: string },当用levelID(类型为string)访问payload[levelID]时,TypeScript只能推断出值的类型是string | { title: string }。而你直接在条件判断和后续代码中重复调用e.tooltipPayload[0].payload[levelID],TypeScript无法确认这两次访问的是同一个值,导致类型收窄不生效。

解决方案

1. 将目标值存入变量后再做类型收窄

这是最简单有效的方法,把访问结果存到变量中,让TypeScript跟踪变量的类型变化:

const handleOpen = (e: HandleOpenEvent) => {
  const tooltipItem = e.tooltipPayload[0];
  const levelID = tooltipItem.name;
  const target = tooltipItem.payload[levelID];
  
  if (typeof target !== "string") {
    console.log(target.title); // 此处类型已正确收窄为{ title: string }
    // setDetailKey(target.title);
  }
};

2. 使用自定义类型守卫函数(严谨场景)

如果需要更明确的类型校验,可以自定义类型守卫来判断值的结构:

function isTitleObject(obj: unknown): obj is { title: string } {
  return typeof obj === 'object' && obj !== null && 'title' in obj;
}

const handleOpen = (e: HandleOpenEvent) => {
  const tooltipItem = e.tooltipPayload[0];
  const levelID = tooltipItem.name;
  const target = tooltipItem.payload[levelID];
  
  if (isTitleObject(target)) {
    console.log(target.title);
    // setDetailKey(target.title);
  }
};

3. 调整接口类型(从根源避免问题)

如果能确定payload中除了name之外的所有键对应的都是{ title: string }类型,可以修改接口定义,去掉索引签名的string类型:

export interface HandleOpenEvent {
  tooltipPayload: {
    dataKey: string;
    name: string;
    payload: {
      name: string;
      [id: string]: { title: string }; // 仅保留对象类型
    };
  }[];
}

修改后,访问payload[levelID]时TypeScript会直接推断为{ title: string },无需额外类型收窄。

注意事项

如果payload中确实存在部分键对应string类型,必须保留类型收窄逻辑,确保访问title前先排除string的情况,避免运行时错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:35:22