]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Fix helpers `Chart` type (#12012)
authorJosh Kelley <joshkel@gmail.com>
Thu, 30 Jan 2025 09:29:19 +0000 (04:29 -0500)
committerGitHub <noreply@github.com>
Thu, 30 Jan 2025 09:29:19 +0000 (10:29 +0100)
helpers.dom.ts functions referenced the internal `Chart` JavaScript class rather than the published `Chart<TType, TData, TLabel>` TypeScript definition. This causes errors when outside code tries to call helper functions.

The two `Chart` interfaces are incompatible - the `width`, `height`, and `currentDevicePixelRatio` properties are declared as readonly in the TS declaration but are manipulated by helpers.dom.ts functions, and helpers.dom.ts functions need to be invoked both by internal Chart.js code (which uses the JS class) and by outside code (which uses the TS types). To address this, I'm importing the JS version as `PrivateChart`. There may be a better solution.

It's my understanding that the comment about "typedefs are auto-exported" is obsolete now that helpers.dom is a native TS file.

Fixes #11153

src/helpers/helpers.dom.ts
test/types/helpers/dom.ts [new file with mode: 0644]

index e06fefe94a6680c82ea645dbc7dd47a3c0bc3b82..bf88ac7d2f0c04760f4b16786ff294e2b50ab4f1 100644 (file)
@@ -1,16 +1,8 @@
 import type {ChartArea, Scale} from '../types/index.js';
-import type Chart from '../core/core.controller.js';
-import type {ChartEvent} from '../types.js';
+import type PrivateChart from '../core/core.controller.js';
+import type {Chart, ChartEvent} from '../types.js';
 import {INFINITY} from './helpers.math.js';
 
-/**
- * Note: typedefs are auto-exported, so use a made-up `dom` namespace where
- * necessary to avoid duplicates with `export * from './helpers`; see
- * https://github.com/microsoft/TypeScript/issues/46011
- * @typedef { import('../core/core.controller.js').default } dom.Chart
- * @typedef { import('../../types').ChartEvent } ChartEvent
- */
-
 /**
  * @private
  */
@@ -112,7 +104,7 @@ function getCanvasPosition(
 
 export function getRelativePosition(
   event: Event | ChartEvent | TouchEvent | MouseEvent,
-  chart: Chart
+  chart: Chart | PrivateChart
 ): { x: number; y: number } {
   if ('native' in event) {
     return event;
@@ -214,7 +206,7 @@ export function getMaximumSize(
  * @returns True if the canvas context size or transformation has changed.
  */
 export function retinaScale(
-  chart: Chart,
+  chart: Chart | PrivateChart,
   forceRatio: number,
   forceStyle?: boolean
 ): boolean | void {
@@ -222,8 +214,8 @@ export function retinaScale(
   const deviceHeight = Math.floor(chart.height * pixelRatio);
   const deviceWidth = Math.floor(chart.width * pixelRatio);
 
-  chart.height = Math.floor(chart.height);
-  chart.width = Math.floor(chart.width);
+  (chart as PrivateChart).height = Math.floor(chart.height);
+  (chart as PrivateChart).width = Math.floor(chart.width);
 
   const canvas = chart.canvas;
 
@@ -238,7 +230,7 @@ export function retinaScale(
   if (chart.currentDevicePixelRatio !== pixelRatio
       || canvas.height !== deviceHeight
       || canvas.width !== deviceWidth) {
-    chart.currentDevicePixelRatio = pixelRatio;
+    (chart as PrivateChart).currentDevicePixelRatio = pixelRatio;
     canvas.height = deviceHeight;
     canvas.width = deviceWidth;
     chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
diff --git a/test/types/helpers/dom.ts b/test/types/helpers/dom.ts
new file mode 100644 (file)
index 0000000..dc1c44f
--- /dev/null
@@ -0,0 +1,11 @@
+import { getRelativePosition } from '../../../src/helpers/helpers.dom.js';
+import { Chart, ChartOptions } from '../../../src/types.js';
+
+const chart = new Chart('test', {
+  type: 'line',
+  data: {
+    datasets: []
+  }
+});
+
+getRelativePosition(new MouseEvent('click'), chart);