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

如何修复Tooltip回调中context.raw.name的TS 2339类型错误?

修复Chart.js中TypeScript提示context.raw.name不存在的错误

问题背景

测试数据:

export const playData = {
  datasets: [
    {
      label: 'Dataset 1',
      showLine: true,
      data: [{ x: 1, y: 10, name: 'John' }, { x: 2, y: 5, name: 'Linda' }, { x: 3, y: 7, name: 'Erin' }, { x: 4, y: 4, name: 'Chloe' }, { x: 5, y: 8, name: 'Paul' }],
      borderColor: 'rgb(255, 99, 132)',
      backgroundColor: 'rgba(255, 99, 132, 0.5)',
    },
  ]
};

自定义Tooltip的组件代码:

export function Chart(props: { chartData: ChartData }) {
  return <Scatter
    data={props.chartData}
    options={{
      responsive: true,
      scales: {
        x: {
          title: {
            display: true,
            text: 'Age (years)'
          },
        },
        y: {
          title: {
            display: true,
            text: 'Change in Height (inches)'
          }
        }
      },
      plugins: {
        legend: {
          position: 'top' as const,
        },
        tooltip: {
          callbacks: {
            label: (context) => {
              return [context.raw.name, `age: ${context.parsed.x} years`, `height change: ${context.parsed.y} in`]
            }
          }
        }
      },
    }}
  />;
}

TypeScript报错:

Property 'name' does not exist on type 'unknown'.ts(2339)

解决方案

方法1:类型断言快速修复

直接给context.raw添加类型断言,明确其包含name属性:

label: (context) => {
  const rawData = context.raw as { x: number; y: number; name: string };
  return [rawData.name, `age: ${context.parsed.x} years`, `height change: ${context.parsed.y} in`]
}

方法2:定义自定义数据类型(推荐)

给图表数据定义明确的TypeScript类型,让类型系统自动识别context.raw的结构:

// 定义单个数据点的类型
interface CustomDataPoint {
  x: number;
  y: number;
  name: string;
}

// 扩展ChartData类型,适配自定义数据结构
interface CustomChartData extends ChartData {
  datasets: Array<{
    label: string;
    showLine?: boolean;
    data: CustomDataPoint[];
    borderColor: string;
    backgroundColor: string;
  }>;
}

// 修改组件props的类型
export function Chart(props: { chartData: CustomChartData }) {
  return <Scatter
    data={props.chartData}
    options={{
      // 其他配置保持不变
      plugins: {
        tooltip: {
          callbacks: {
            label: (context) => {
              // 此时context.raw会自动推导为CustomDataPoint类型
              return [context.raw.name, `age: ${context.parsed.x} years`, `height change: ${context.parsed.y} in`]
            }
          }
        }
      },
    }}
  />;
}

方法3:类型守卫做安全校验

如果需要兼容数据可能缺失name的场景,用类型守卫做安全检查:

label: (context) => {
  // 定义类型守卫函数
  function hasName(data: unknown): data is { name: string } {
    return typeof data === 'object' && data !== null && 'name' in data;
  }

  const name = hasName(context.raw) ? context.raw.name : 'Unknown';
  return [name, `age: ${context.parsed.x} years`, `height change: ${context.parsed.y} in`]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:30:54