Chart.js
Chart.js copied to clipboard
Types: `scale.title` does not exist when a `legend` `onClick` handler is specified
Expected behavior
After creating a Chart
, I want to update its colors dynamically. I understand that I can't directly say chart.options.scales.x.title.color
because the properties starting with scales
are optional. However, I expect to be able to test chart.options.scales?.x?.title?.color === undefined
, and if that's false
, TypeScript should allow me to assign a new color to chart.options.scales.x.title.color
.
Current behavior
Under certain conditions, TypeScript 4.7.4 emits an error when I try to access title
:
Property 'title' does not exist on type '_DeepPartialObject<{ type: "linear"; } & CartesianScaleOptions & { beginAtZero: boolean; suggestedMin?: number | undefined; suggestedMax?: number | undefined; grace?: string | number | undefined; ticks: { ...; }; }> | ... 4 more ... | _DeepPartialObject<...>'.
Property 'title' does not exist on type '_DeepPartialObject<{ type: "radialLinear"; } & CoreScaleOptions & { animate: boolean; startAngle: number; angleLines: { display: boolean; color: Scriptable<Color, ScriptableScaleContext>; lineWidth: Scriptable<...>; borderDash: Scriptable<...>; borderDashOffset: Scriptable<...>; }; ... 7 more ...; ticks: RadialTickO...'.
The conditions appear to be:
- A
legend
onClick
handler is specified. - The error goes away if I change the handler's third parameter from
LegendElement<ChartType>
toany
. - The error goes away if I omit the handler entirely.
- The error never happens with
ticks
, only withtitle
. I am not sure whytitle
is special.
Reproducible sample
https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgYQBYENYBoUdgUQDcBTAOxhzUxgBUBPMYnAGWIHMyATfAG2JDIU4rDqU4BJGPxxR2wAM5So6AEZ95cAL5wAZlAgg4AcgDGeGADoAVvKMBuALAAoKrAuy2CpQAoLfj17EymrE8gCUjk7OOgCupCYwwBCkcHyinAD6JjzAJgDWGRhifFDeGcQk5ABcuNREgjgZaVwZwFIgNSJcktJwTexcnQNivPyCADyutAzEAHxhiJrOzibJinCK6DAx8lnmcAC8cKTEAO61sN5Gm9vyU0Y4CM5wL3AwMzVGOScPz6+cW3QNSeTleYLgAJg6HkxBg8hqAG0-uDwSCUej-oDEciMbikAAPGoARgADDg6DUACxaLA43Hogk1ABMZLgFLgAE4aXT6ai4IS4ABmVnsokANm5oN5YIAurSpdKXjxVMQeJ8TFtbPLpZptei5TjdTiIGBEmtgTyXmAeDFPKR4YhLeDmmILQrFclkDl8jUXZlsrkCkVOCU9fSje6wRGMfINeo3dKBWjFS93oxPt9iJgjHBoXBVvaKE6MYkYHwEynwaseNBPgBiQWNpu-SOVzgKa3odkwKAxJjF3lSfEwT4CCCnFuVyVTxL5B3Jqcvau14wNpuNyeV6O87f09kIXfgw8RzQRZZOAvrWPoPiHDZQ257agWE1m+0Wa-qAD8FnxkWcwA6HA3ifsQhwHEccScMQOjACcnBwAAPohGxxsQFilreEGQWIMFwcQCHIahN7obOeQaNhcBQXh8ELAubyoPo5wnOc+BQPopRGAA6gA8jxABiRhnk4SxRE4oEYW0fAWMuUB3kYdb8fxJIqSS9jOBJZHyDJEA1nJRwKapJJKepYk3DsT5uDEYCQsQ3jCUAA
Optional extra steps/info to reproduce
Here's a CodePen (with TypeScript types commented out), showing that this works at runtime: https://codepen.io/StephanTLavavej/pen/GRxKJgz
TypeScript examples:
- original repro with error
-
error vanishes if handler's third parameter is
any
- error vanishes if handler is removed entirely
Possible solution
No response
Context
I'm implementing dark mode for the microsoft/STL Status Chart at https://microsoft.github.io/STL/ . I converted it to use TypeScript a couple of months ago, but haven't tried to change colors dynamically until now.
chart.js version
v3.8.0
Browser name and version
Chrome 103.0.5060.53
Link to your project
No response
What I think happens is that the legend causes the type of the scale to be any of the scales. Since the RadialLinearScaleOptions
don't have a title, this error appears. https://github.com/chartjs/Chart.js/blob/master/types/index.esm.d.ts#L3345-L3456
I was able to resolve the error by changing the type definition for the 3rd argument of the legend callback to _legend: LegendElement<'line'>
. If your chart is always a line chart this seems like the correct solution.
Another option is to make the click handler an arrow function onClick: (_event, _legend_item, _legend) => {}
and then the types for all 3 arguments appear automatically
Thanks! I have both 'line'
and 'bar' | 'line'
charts, which made things more complicated, but I was able to get this working.
I think 'bar' |
line'` should be fine since those are both cartesian charts and thus can use the same axis types.