chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.36k stars 11.89k forks source link

htmlLegend is missing in PluginOptionsByType in TypeScript 5.5.3 definitions #11877

Open tedbrosby opened 3 weeks ago

tedbrosby commented 3 weeks ago

Expected behavior

When declaring a ChartOptions with a declared type, IE:

private doughnutOptions: ChartOptions<"doughnut"> 

And initializing the options with a custom html legend,

this.doughnutOptions = {
    plugins: { 
        ...  
        htmlLegend: {
            containerId: `myContainerId`,
        }
    }    
}  

There should be no lint errors on eslint.

Current behavior

When declaring ChartOptions with the above syntax, the following error is observed:

Object literal may only specify known properties, and 'htmlLegend' does not exist in type '_DeepPartialObject<PluginOptionsByType<"doughnut">>'.ts(2353)  

This error can be cleared by changing the variable for chart options to:

private doughnutOptions: ChartOptions<any>  

However, this fails our lint for typescript/no-redundant-type-constituents.
For now, we are considering disabling lint for that line, but we would like to know, is there something we're doing wrong that htmlLegend is not appearing anywhere in our TypeScript definitions for chart.js? We are on version 4.4.3.

Reproducible sample

https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgYQBYENZwL5wGZQQhwDkAxhrAHQBWAziQNwCwAUGwG6ZxkwAecALxwAJhDIBXEAFMAdjCoBzaTACiAG2kz5AIQCeASREAKAEQg9aTDFMBKOOjpwAEgBUAsgBlk6WVzoaWnIwLKxcUHAWVljCstIA7iiUMMa8fAA0iGxwOXAwemDSAFykYhKKqLISMCTp2bki6DDoJQj1ubnq6ABG0up0JQDapgBK0iKmmaY66hLSk3CmAJp96hDxC6YA4lDScpsAChJQYJqbAPJQvsqmALp1rB0djc10KgNwg22PT79dveoSiQAMRwCB4OAANQgMGkDAev1+LxanwAjAAmTKogCcmQAzJkAKyZTFwPH3dpPbC3SnYBG5CBgGDACCyD7fX6ncrANmtSkdTTKWQiPk-RGiYB0U7oPQlPDofrSem-On83KoGAgdSeaRCkVZMWIsis5o86RQIwlUyCuQiIyTNU5VWGp3K3J0MgKuGi8V8H3iuCOnBujqyg0BwMu3LYNUxw1x7C2RhAA

Optional extra steps/info to reproduce

No response

Possible solution

No response

Context

We are using a custom html legend for our doughnut charts

chart.js version

v4.4.3

Browser name and version

No response

Link to your project

No response

tedbrosby commented 3 weeks ago

I found this: https://github.com/chartjs/Chart.js/issues/5070#issuecomment-1164405394

However, when declaring a file: chart-options.d.ts (Should it have a different name?)

I wrote the following:

import type { ChartType } from "chart.js";

declare module 'chart.js' {
   interface PluginOptionsByType<TType extends ChartType = ChartType> {
      htmlLegend?: {
         containerId: string
      };
   }
}

And I get error 'TType' is defined but never used.eslint[typescript/no-unused-vars](https://typescript-eslint.io/rules/no-unused-vars)

LeeLenaleee commented 3 weeks ago

As you found out you can use type declaration merging to make your plugin type safe. For now you will need to ignore the unused vars error since as far as I can see TS demands you to have the same signature.

I have a opened a PR but I think we might need to wait with that till V5 before we can merge that since it might be technically breaking

LeeLenaleee commented 3 weeks ago

It does not seem possible to fix this now without breaking current implementations. With the fix I found I am not sure if we do want to fix this because it makes using the plugins normally for setting defaults a lot more difficult.

For now ignoring the unused var rule would be the best solution