diff --git a/example/src/App.tsx b/example/src/App.tsx index a8546cc7..3cfd2188 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -9,6 +9,8 @@ import { SkiaChart, } from '@wuba/react-native-echarts'; import * as echarts from 'echarts/core'; +import type { EChartsOption } from 'echarts'; +import type { ChartElement } from '@wuba/react-native-echarts'; import { BarChart, LineChart } from 'echarts/charts'; import { TitleComponent, @@ -31,11 +33,11 @@ echarts.use([ const E_HEIGHT = 250; const E_WIDTH = Dimensions.get('screen').width; -function SkiaComponent({ option }: any) { - const skiaRef = useRef(null); +function SkiaComponent({ option }: { option: EChartsOption }) { + const skiaRef = useRef<(ChartElement & any) | null>(null); useEffect(() => { - let chart: any; + let chart: echarts.EChartsType | undefined; if (skiaRef.current) { chart = echarts.init(skiaRef.current, 'light', { // @ts-ignore @@ -51,11 +53,11 @@ function SkiaComponent({ option }: any) { return ; } -function SvgComponent({ option }: any) { - const svgRef = useRef(null); +function SvgComponent({ option }: { option: EChartsOption }) { + const svgRef = useRef<(ChartElement & any) | null>(null); useEffect(() => { - let chart: any; + let chart: echarts.EChartsType | undefined; if (svgRef.current) { chart = echarts.init(svgRef.current, 'light', { renderer: 'svg', @@ -75,29 +77,29 @@ const fontFamily = Platform.select({ }); const option = { xAxis: { - type: 'category', + type: 'category' as const, data: ['周一', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], }, yAxis: { - type: 'value', + type: 'value' as const, }, tooltip: { - trigger: 'axis', + trigger: 'axis' as const, }, series: [ { data: [120, 200, 150, 80, 70, 110, 130], - type: 'bar', + type: 'bar' as const, }, { data: [220, 100, 180, 160, 150, 120, 110], - type: 'line', + type: 'line' as const, }, ], textStyle: { fontFamily, }, -}; +} as EChartsOption; function App() { return ( diff --git a/src/__tests__/chart.test.tsx b/src/__tests__/chart.test.tsx index f4b27464..f3946ca1 100644 --- a/src/__tests__/chart.test.tsx +++ b/src/__tests__/chart.test.tsx @@ -17,6 +17,13 @@ import SVGComponent from '../svg/svgChart'; import { dispatchEventsToZRender } from '../components/events'; import { SVGRenderer } from '../svg/SVGRenderer'; import * as echarts from 'echarts/core'; +import type { EChartsType } from 'echarts/core'; +import type { + RNGestureHandlerGesture, + ChartElement, + DefaultRNGestures, + DispatchEvents, +} from '../types'; import { BarChart, LineChart, GraphChart, ScatterChart } from 'echarts/charts'; import { PanGesture, @@ -108,7 +115,7 @@ function getOptionTwo() { animation: false, tooltip: {}, animationDurationUpdate: 1500, - animationEasingUpdate: 'quinticInOut', + animationEasingUpdate: 'quinticInOut' as any, // Temporarily cast to any for test series: [ { type: 'graph', @@ -244,8 +251,8 @@ function zoomElement(pan: ReactTestInstance, x: number, y: number) { } interface ChartCall { - call: (chart: any) => void; - snapshot?: (data: string) => any; + call: (chart: EChartsType) => void; + snapshot?: (data: string) => Promise; } function Chart({ @@ -255,15 +262,15 @@ function Chart({ gesture, handleGesture = true, }: { - Component: React.ComponentType; + Component: React.ComponentType; // Keep as any to allow both SkiaChartProps and SVGChartProps with ref calls?: ChartCall[]; useRNGH?: boolean; - gesture?: any; + gesture?: RNGestureHandlerGesture; handleGesture?: boolean; }) { - const ref = useRef(null); + const ref = useRef<(ChartElement & any) | null>(null); useEffect(() => { - let chart: any; + let chart: EChartsType | undefined; if (ref.current) { // @ts-ignore chart = echarts.init(ref.current, 'light', { @@ -273,17 +280,19 @@ function Chart({ }); (async () => { for (const call of calls) { - call.call(chart); - if (call.snapshot) { - await new Promise((resolve) => - setTimeout(async () => { - const result = call.snapshot?.(chart.getDataURL()); - if (result instanceof Promise) { - await result; - } - resolve(undefined); - }, 0) - ); + if (chart) { + call.call(chart); + if (call.snapshot) { + await new Promise((resolve) => + setTimeout(async () => { + const result = call.snapshot?.(chart!.getDataURL()); + if (result instanceof Promise) { + await result; + } + resolve(undefined); + }, 0) + ); + } } } })(); @@ -314,7 +323,7 @@ Components.forEach((Component) => { Component={Component} calls={[ { - call: (chart: any) => { + call: (chart: EChartsType) => { chart.setOption(getOption('line')); }, snapshot, @@ -333,13 +342,13 @@ Components.forEach((Component) => { { + call: (chart: EChartsType) => { act(() => chart.setOption(getOption())); }, snapshot, }, { - call: (chart: any) => { + call: (chart: EChartsType) => { const id = chart.getZr().id; act(() => dispatchEventsToZRender( @@ -373,7 +382,7 @@ Components.forEach((Component) => { handleGesture={false} calls={[ { - call: (chart: any) => { + call: (chart: EChartsType) => { chart.setOption(getOption('scatter')); }, snapshot, @@ -393,7 +402,7 @@ Components.forEach((Component) => { Component={Component} calls={[ { - call: (chart: any) => { + call: (chart: EChartsType) => { chart.setOption(getOptionTwo()); }, snapshot, @@ -435,7 +444,7 @@ Components.forEach((Component) => { useRNGH calls={[ { - call: (chart: any) => { + call: (chart: EChartsType) => { chart.setOption(getOptionTwo()); }, snapshot, @@ -495,9 +504,12 @@ Components.forEach((Component) => { { - gesture(...args); - return args[0]; + gesture={( + defaultGestures: DefaultRNGestures, + dispatchEvents: DispatchEvents + ) => { + gesture(defaultGestures, dispatchEvents); + return defaultGestures[0]; }} /> ); diff --git a/src/skia/graphic.tsx b/src/skia/graphic.tsx index e7eadaf9..e26fe1b4 100644 --- a/src/skia/graphic.tsx +++ b/src/skia/graphic.tsx @@ -43,11 +43,13 @@ import { } from '@shopify/react-native-skia'; import React from 'react'; -function isImageLike(val: any): val is HTMLImageElement { - return val && isString(val.src); +function isImageLike(val: unknown): val is HTMLImageElement { + return val != null && typeof val === 'object' && isString((val as any).src); } -function isCanvasLike(val: any): val is HTMLCanvasElement { - return val && isFunction(val.toDataURL); +function isCanvasLike(val: unknown): val is HTMLCanvasElement { + return ( + val != null && typeof val === 'object' && isFunction((val as any).toDataURL) + ); } type SVGVNodeAttrs = Record< diff --git a/src/types.ts b/src/types.ts index 90e3fac8..9f6657d8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,7 +21,7 @@ export type HandlerName = export type DispatchEvents = ( types: HandlerName[], nativeEvent: any, - eventArgs?: any + eventArgs?: Record ) => void; export type DefaultRNGestures = [PanGesture, PinchGesture, TapGesture];