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

Chart.js升级3.8.0后设置options.scales.x.time报TS2339错误

问题描述

将项目中chart.js从2.9.4版本升级至3.8.0版本时,ChartConfiguration类型下options.scales.x的time属性出现TypeScript类型缺失报错,给options.scales.x.time.unit赋值时触发如下错误:

error TS2339: Property 'time' does not exist on type 
'_DeepPartialObject<{ type: "linear"; } & CartesianScaleOptions & { beginAtZero: boolean; suggestedMin?: number; suggestedMax?: number; grace?: string | number; ticks: { format: NumberFormatOptions; precision: number; stepSize: number; count: number; }; }> | _DeepPartialObject<...> | _DeepPartialObject<...> | _DeepPa...'.

最初怀疑问题和ng2-charts库有关,但移除该依赖后问题仍可复现。

最小复现代码
import { Component, OnInit } from '@angular/core';
import { ChartConfiguration } from 'chart.js';

@Component({
  selector: 'daily-chart',
  templateUrl: './daily-chart.component.html',
  styleUrls: ['./daily-chart.component.scss']
})
export class DailyChartComponent implements OnInit {
  chartConfig: ChartConfiguration<'line'> = {
    data: {
      datasets: []
    },
    type: 'line',
    options: {
      scales: {
        x: {
          type: 'time',
          time: {
            unit: 'day',
          },
        }
      }
    }
  }

  constructor() { }

  ngOnInit() {
    this.chartConfig.options.scales.x.time.unit = 'week'; // 报错行
  }
}
项目依赖版本
  • chart.js: 3.8.0
  • ng2-charts: 3.0.11
  • angular: 13.3.5
  • tslib: 2.4.0
  • typescript: 4.6.4
  • chartjs-adapter-moment: 1.0.0
  • chartjs-plugin-annotation: 1.4.0
  • chartjs-plugin-datalabels: 2.0.0
问题原因

这个问题和ng2-charts无关,是Chart.js 3.x的类型设计+TypeScript类型收窄规则共同导致的:

  1. Chart.js 3.x对不同类型的坐标轴做了严格的类型区分:线性轴、类别轴、时间轴等各自有独立的配置类型,只有时间轴(type: 'time')的类型定义上才存在time配置属性。
  2. 初始化chartConfig时,TypeScript会根据传入的对象字面量做上下文类型推断,识别到x轴设置了type: 'time',所以初始化阶段写time配置不会报错。
  3. 但在ngOnInit中动态访问this.chartConfig.options.scales.x时,TypeScript是基于ChartConfiguration<'line'>的公开声明类型做校验,这个类型里scales.x是所有支持的坐标轴类型的联合类型,不会保留初始化时传入的字面量type: 'time'的信息。联合类型中除了时间轴之外的其他坐标轴类型都没有time属性,因此访问时触发类型报错。
  4. Chart.js 2.x的类型定义比较宽松,没有做这种按坐标轴类型的严格属性校验,所以升级前不会出现该问题。
修复方案

任选以下一种方案即可解决:

方案1:访问时做显式类型断言(改动最小)

导入Chart.js内置的TimeScaleOptions类型,在访问x轴配置时做类型断言,明确告知TypeScript该轴为时间轴:

import { ChartConfiguration, TimeScaleOptions } from 'chart.js';

// ...其他代码不变
ngOnInit() {
  (this.chartConfig.options.scales.x as TimeScaleOptions).time.unit = 'week';
}

方案2:初始化时明确x轴的类型

在配置x轴时直接断言为TimeScaleOptions类型,让TypeScript从初始化阶段就确定x轴的类型:

chartConfig: ChartConfiguration<'line'> = {
  // data、type配置不变
  options: {
    scales: {
      x: {
        type: 'time',
        time: {
          unit: 'day',
        },
      } as TimeScaleOptions
    }
  }
}

修改后后续访问this.chartConfig.options.scales.x.time不会再报类型错误。

方案3:抽离坐标轴配置为独立变量

把时间轴的配置抽成带明确类型的独立变量,初始化时引用这个变量,后续修改配置直接操作独立变量即可,不需要从chartConfig深层取值:

private xTimeScale: TimeScaleOptions = {
  type: 'time',
  time: {
    unit: 'day'
  }
};

chartConfig: ChartConfiguration<'line'> = {
  data: { datasets: [] },
  type: 'line',
  options: {
    scales: {
      x: this.xTimeScale
    }
  }
}

ngOnInit() {
  this.xTimeScale.time.unit = 'week'; // 无类型报错
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:01:58