From 598ce2a961b6eeae2232da3b4fd4f2fb3ebd6a77 Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Wed, 29 Jan 2025 11:17:01 -0500 Subject: [PATCH] Fix helpers `Chart` type helpers.dom.ts functions referenced the internal `Chart` JavaScript class rather than the published `Chart` 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 | 22 +++++++--------------- test/types/helpers/dom.ts | 11 +++++++++++ 2 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 test/types/helpers/dom.ts diff --git a/src/helpers/helpers.dom.ts b/src/helpers/helpers.dom.ts index e06fefe94a6..bf88ac7d2f0 100644 --- a/src/helpers/helpers.dom.ts +++ b/src/helpers/helpers.dom.ts @@ -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 index 00000000000..dc1c44f5066 --- /dev/null +++ b/test/types/helpers/dom.ts @@ -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);