You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/02/28 15:59:44 UTC

[incubator-echarts] branch typescript updated: ts: add types for axisPointer

This is an automated email from the ASF dual-hosted git repository.

shenyi pushed a commit to branch typescript
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git


The following commit(s) were added to refs/heads/typescript by this push:
     new 286efe8  ts: add types for axisPointer
286efe8 is described below

commit 286efe81d787cbfce73edf8573223e8c49b71a26
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Feb 28 23:59:11 2020 +0800

    ts: add types for axisPointer
---
 src/chart/effectScatter.ts                         |   2 -
 src/component/axisPointer.ts                       |   6 +-
 .../axisPointer/{IAxisPointer => AxisPointer.ts}   |  44 ++--
 src/component/axisPointer/AxisPointerModel.ts      | 117 ++-------
 src/component/axisPointer/BaseAxisPointer.ts       | 274 ++++++++++++---------
 src/component/axisPointer/CartesianAxisPointer.ts  |  77 ++++--
 src/component/axisPointer/PolarAxisPointer.ts      |  57 ++++-
 src/component/axisPointer/SingleAxisPointer.ts     |  70 ++++--
 src/component/axisPointer/axisTrigger.ts           | 242 ++++++++++++------
 src/component/axisPointer/findPointFromSeries.ts   |  31 ++-
 src/component/axisPointer/modelHelper.ts           | 186 +++++++++-----
 src/component/axisPointer/viewHelper.ts            | 132 ++++++----
 src/component/tooltip/TooltipView.ts               |  13 +-
 src/coord/Axis.ts                                  |   4 +-
 src/coord/CoordinateSystem.ts                      |   5 +-
 src/coord/axisModelCommonMixin.ts                  |   1 -
 src/coord/polar/AxisModel.ts                       |   2 +
 src/coord/polar/prepareCustom.ts                   |   3 +-
 src/coord/single/Single.ts                         |   2 +-
 src/model/Model.ts                                 |   4 -
 src/model/Series.ts                                |  20 +-
 src/model/mixin/areaStyle.ts                       |   4 +-
 src/model/mixin/itemStyle.ts                       |   6 +-
 src/model/mixin/lineStyle.ts                       |   2 +-
 src/model/mixin/makeStyleMapper.ts                 |   2 +-
 src/util/graphic.ts                                |   2 +-
 src/util/model.ts                                  |  10 +-
 src/util/types.ts                                  |  99 +++++++-
 src/visual/symbol.ts                               |   2 +-
 29 files changed, 894 insertions(+), 525 deletions(-)

diff --git a/src/chart/effectScatter.ts b/src/chart/effectScatter.ts
index 5be4e3b..31391f1 100644
--- a/src/chart/effectScatter.ts
+++ b/src/chart/effectScatter.ts
@@ -17,8 +17,6 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as echarts from '../echarts';
 
 import './effectScatter/EffectScatterSeries';
diff --git a/src/component/axisPointer.ts b/src/component/axisPointer.ts
index a846a31..3cb58ff 100644
--- a/src/component/axisPointer.ts
+++ b/src/component/axisPointer.ts
@@ -16,19 +16,19 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-// @ts-nocheck
+
 import * as echarts from '../echarts';
 import * as zrUtil from 'zrender/src/core/util';
 import * as axisPointerModelHelper from './axisPointer/modelHelper';
 import axisTrigger from './axisPointer/axisTrigger';
 
-import './axisPointer/AxisPointerModel';
 import './axisPointer/AxisPointerView';
 
 // CartesianAxisPointer is not supposed to be required here. But consider
 // echarts.simple.js and online build tooltip, which only require gridSimple,
 // CartesianAxisPointer should be able to required somewhere.
 import './axisPointer/CartesianAxisPointer';
+import AxisPointerModel from './axisPointer/AxisPointerModel';
 
 echarts.registerPreprocessor(function (option) {
     // Always has a global axisPointerModel for default setting.
@@ -51,7 +51,7 @@ echarts.registerPreprocessor(function (option) {
 echarts.registerProcessor(echarts.PRIORITY.PROCESSOR.STATISTIC, function (ecModel, api) {
     // Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
     // allAxesInfo should be updated when setOption performed.
-    ecModel.getComponent('axisPointer').coordSysAxesInfo =
+    (ecModel.getComponent('axisPointer') as AxisPointerModel).coordSysAxesInfo =
         axisPointerModelHelper.collect(ecModel, api);
 });
 
diff --git a/src/component/axisPointer/IAxisPointer b/src/component/axisPointer/AxisPointer.ts
similarity index 53%
rename from src/component/axisPointer/IAxisPointer
rename to src/component/axisPointer/AxisPointer.ts
index 8fbd1f3..3c71adb 100644
--- a/src/component/axisPointer/IAxisPointer
+++ b/src/component/axisPointer/AxisPointer.ts
@@ -1,8 +1,8 @@
 /*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
+* distributed with this work for additional information
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
@@ -17,25 +17,25 @@
 * under the License.
 */
 
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
+import ExtensionAPI from '../../ExtensionAPI';
+import { CommonAxisPointerOption } from '../../util/types';
+import Model from '../../model/Model';
 
-/**
- * AxisPointer Interface:
- *
- *
- * Instance members:
- *
- *  + render {Function}: mandatory.
- *      If `show` called, axisPointer must be displayed or remain its original status.
- *      @param {module:echarts/model/Model} axisModel
- *      @param {module:echarts/model/Model} axisPointerModel
- *      @param {module:echarts/coord/ICoordinateSystem} coordSys
- *      @param {module:echarts/ExtensionAPI} api
- *      @param {boolean} forceRender
- *
- *  + remove {Function}: mandatory.
- *      If `hide` called, axisPointer must be hidden.
- *      @param {module:echarts/ExtensionAPI} api
- *
- *  + dispose {Function}: mandatory
- *      @param {module:echarts/ExtensionAPI} api
- */
\ No newline at end of file
+export interface AxisPointer {
+    /**
+     * If `show` called, axisPointer must be displayed or remain its original status.
+     */
+    render(
+        axisModel: AxisBaseModel,
+        axisPointerModel: Model<CommonAxisPointerOption>,
+        // coordSys: CoordinateSystem,
+        api: ExtensionAPI,
+        forceRender?: boolean
+    ): void
+    /**
+     * If `hide` called, axisPointer must be hidden.
+     */
+    remove(api: ExtensionAPI): void
+    dispose(api: ExtensionAPI): void
+}
\ No newline at end of file
diff --git a/src/component/axisPointer/AxisPointerModel.ts b/src/component/axisPointer/AxisPointerModel.ts
index dae81f0..dbf7d5b 100644
--- a/src/component/axisPointer/AxisPointerModel.ts
+++ b/src/component/axisPointer/AxisPointerModel.ts
@@ -20,20 +20,15 @@
 import ComponentModel from '../../model/Component';
 import {
     ComponentOption,
-    OptionDataValue,
-    LineStyleOption,
-    AreaStyleOption,
-    LabelOption,
-    ZREasing,
-    ColorString,
-    ShadowOptionMixin,
-    CallbackDataParams
+    ScaleDataValue,
+    CommonAxisPointerOption
 } from '../../util/types';
 
-interface AxisInfo {
+interface MapperParamAxisInfo {
     axisIndex: number
     axisName: string
     axisId: string
+    axisDim: string
 }
 
 interface AxisPointerLink {
@@ -56,101 +51,17 @@ interface AxisPointerLink {
     singleAxisName?: string[] | string
 
     mapper?(
-        sourceVal: OptionDataValue,
-        sourceAxisInfo: AxisInfo,
-        targetAxisInfo: AxisInfo
-    ): OptionDataValue
+        sourceVal: ScaleDataValue,
+        sourceAxisInfo: MapperParamAxisInfo,
+        targetAxisInfo: MapperParamAxisInfo
+    ): CommonAxisPointerOption['value']   // TODO: TYPE Should return numeric value or category value?
 }
 
-type LabelFormatterParmas = Pick<CallbackDataParams,
-    'componentType'
-    | 'componentSubType'
-    | 'componentIndex'
-    | 'seriesType'
-    | 'seriesIndex'
-    | 'seriesId'
-    | 'seriesName'
-    | 'name'
-    | 'dataIndex'
-    | 'data'
-    | 'dataType'
-    | 'value'
-    | 'dimensionNames'
-    | 'dimensionIndex'
->
-
-export interface AxisPointerOption extends ComponentOption {
-
-    show?: boolean | 'auto'
-
-    triggerOn?: 'click' | 'mousemove' | 'none' | 'mousemove|click'
-
-    type?: 'line' | 'shadow'
-
-    snap?: boolean
-
-    triggerTooltip?: boolean
-
-    /**
-     * current value. When using axisPointer.handle, value can be set to define the initail position of axisPointer.
-     */
-    value?: OptionDataValue
-
-    status?: 'show' | 'hide'
-
-    // [group0, group1, ...]
-    // Each group can be: {
-    //      mapper: function () {},
-    //      singleTooltip: 'multiple',  // 'multiple' or 'single'
-    //      xAxisId: ...,
-    //      yAxisName: ...,
-    //      angleAxisIndex: ...
-    // }
-    // mapper: can be ignored.
-    //      input: {axisInfo, value}
-    //      output: {axisInfo, value}
-    link?: AxisPointerLink[]
+// TODO: TYPE AxisPointerOption for each axis
+export interface AxisPointerOption extends ComponentOption, Omit<CommonAxisPointerOption, 'type'> {
+    type?: 'line' | 'shadow' | 'cross' | 'none'
 
-    label?: LabelOption & {
-        precision?: 'auto' | string
-        margin?: number
-        /**
-         * String template include variable {value} or callback function
-         */
-        formatter?: string | ((params: LabelFormatterParmas) => string)
-    }
-    animation?: boolean | 'auto'
-    animationDurationUpdate?: number
-    animationEasingUpdate?: ZREasing
-
-    /**
-     * Available when type is 'line'
-     */
-    lineStyle?: LineStyleOption
-    /**
-     * Available when type is 'shadow'
-     */
-    shadowStyle?: AreaStyleOption
-
-    handle?: {
-        show?: boolean
-        icon?: string
-        /**
-         * The size of the handle
-         */
-        size?: number | number[]
-        /**
-         * Distance from handle center to axis.
-         */
-        margin?: number
-
-        color?: ColorString
-
-        /**
-         * Throttle for mobile performance
-         */
-        throttle?: number
-    } & ShadowOptionMixin
+    link?: AxisPointerLink[]
 }
 
 
@@ -159,7 +70,9 @@ class AxisPointerModel extends ComponentModel<AxisPointerOption> {
     static type = 'axisPointer' as const
     type = AxisPointerModel.type
 
-    // coordSysAxesInfo
+    // Will be injected and read in modelHelper and axisTrigger
+    // No need to care about it.
+    coordSysAxesInfo: unknown
 
     static defaultOption: AxisPointerOption = {
         // 'auto' means that show when triggered by tooltip or handle.
diff --git a/src/component/axisPointer/BaseAxisPointer.ts b/src/component/axisPointer/BaseAxisPointer.ts
index be5fd82..f6b3316 100644
--- a/src/component/axisPointer/BaseAxisPointer.ts
+++ b/src/component/axisPointer/BaseAxisPointer.ts
@@ -17,75 +17,114 @@
 * under the License.
 */
 
-// @ts-nocheck
 
 import * as zrUtil from 'zrender/src/core/util';
-import * as clazzUtil from '../../util/clazz';
 import * as graphic from '../../util/graphic';
 import * as axisPointerModelHelper from './modelHelper';
 import * as eventTool from 'zrender/src/core/event';
 import * as throttleUtil from '../../util/throttle';
 import {makeInner} from '../../util/model';
-
-var inner = makeInner();
+import { AxisPointer } from './AxisPointer';
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
+import { VectorArray } from 'zrender/src/core/vector';
+import ExtensionAPI from '../../ExtensionAPI';
+import Displayable, { DisplayableProps } from 'zrender/src/graphic/Displayable';
+import Element from 'zrender/src/Element';
+import { VerticalAlign, HorizontalAlign, CommonAxisPointerOption } from '../../util/types';
+import { PathProps } from 'zrender/src/graphic/Path';
+import Model from '../../model/Model';
+
+var inner = makeInner<{
+    lastProp?: DisplayableProps
+    labelEl?: graphic.Rect
+    pointerEl?: Displayable
+}>();
 var clone = zrUtil.clone;
 var bind = zrUtil.bind;
 
-/**
- * Base axis pointer class in 2D.
- * Implemenents {module:echarts/component/axis/IAxisPointer}.
- */
-function BaseAxisPointer() {
+type Icon = ReturnType<typeof graphic.createIcon>
+interface Transform {
+    position: VectorArray,
+    rotation: number
 }
 
-BaseAxisPointer.prototype = {
+type AxisValue = CommonAxisPointerOption['value']
 
-    /**
-     * @private
-     */
-    _group: null,
+// Not use top level axisPointer model
+type AxisPointerModel = Model<CommonAxisPointerOption>
 
-    /**
-     * @private
-     */
-    _lastGraphicKey: null,
+interface BaseAxisPointer {
 
     /**
-     * @private
+     * Should be implemenented by sub-class if support `handle`.
      */
-    _handle: null,
+    getHandleTransform(value: AxisValue, axisModel: AxisBaseModel, axisPointerModel: AxisPointerModel): Transform
 
     /**
-     * @private
+     * * Should be implemenented by sub-class if support `handle`.
      */
-    _dragging: false,
+    updateHandleTransform(
+        transform: Transform,
+        delta: number[],
+        axisModel: AxisBaseModel,
+        axisPointerModel: AxisPointerModel
+    ): Transform & {
+        cursorPoint: number[]
+        tooltipOption?: {
+            verticalAlign?: VerticalAlign
+            align?: HorizontalAlign
+        }
+    }
 
-    /**
-     * @private
-     */
-    _lastValue: null,
+}
 
-    /**
-     * @private
-     */
-    _lastStatus: null,
+export interface AxisPointerElementOptions {
+    graphicKey: string
+
+    pointer: PathProps & {
+        type: 'Line' | 'Rect' | 'Circle' | 'Sector'
+    }
+
+    label: PathProps
+}
+/**
+ * Base axis pointer class in 2D.
+ */
+class BaseAxisPointer implements AxisPointer {
+
+    private _group: graphic.Group
+
+    private _lastGraphicKey: string
+
+    private _handle: Icon
+
+    private _dragging = false
+
+    private _lastValue: AxisValue
+
+    private _lastStatus: CommonAxisPointerOption['status']
+
+    private _payloadInfo: ReturnType<BaseAxisPointer['updateHandleTransform']>
 
     /**
-     * @private
+     * If have transition animation
      */
-    _payloadInfo: null,
+    private _moveAnimation: boolean
+
+    private _axisModel: AxisBaseModel
+    private _axisPointerModel: AxisPointerModel
+    private _api: ExtensionAPI
 
     /**
      * In px, arbitrary value. Do not set too small,
      * no animation is ok for most cases.
-     * @protected
      */
-    animationThreshold: 15,
+    protected animationThreshold = 15
 
     /**
      * @implement
      */
-    render: function (axisModel, axisPointerModel, api, forceRender) {
+    render(axisModel: AxisBaseModel, axisPointerModel: AxisPointerModel, api: ExtensionAPI, forceRender?: boolean) {
         var value = axisPointerModel.get('value');
         var status = axisPointerModel.get('status');
 
@@ -120,7 +159,7 @@ BaseAxisPointer.prototype = {
         handle && handle.show();
 
         // Otherwise status is 'show'
-        var elOption = {};
+        var elOption = {} as AxisPointerElementOptions;
         this.makeElOption(elOption, value, axisModel, axisPointerModel, api);
 
         // Enable change axis pointer type.
@@ -141,33 +180,33 @@ BaseAxisPointer.prototype = {
         }
         else {
             var doUpdateProps = zrUtil.curry(updateProps, axisPointerModel, moveAnimation);
-            this.updatePointerEl(group, elOption, doUpdateProps, axisPointerModel);
+            this.updatePointerEl(group, elOption, doUpdateProps);
             this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
         }
 
         updateMandatoryProps(group, axisPointerModel, true);
 
         this._renderHandle(value);
-    },
+    }
 
     /**
      * @implement
      */
-    remove: function (api) {
+    remove(api: ExtensionAPI) {
         this.clear(api);
-    },
+    }
 
     /**
      * @implement
      */
-    dispose: function (api) {
+    dispose(api: ExtensionAPI) {
         this.clear(api);
-    },
+    }
 
     /**
      * @protected
      */
-    determineAnimation: function (axisModel, axisPointerModel) {
+    determineAnimation(axisModel: AxisBaseModel, axisPointerModel: AxisPointerModel): boolean {
         var animation = axisPointerModel.get('animation');
         var axis = axisModel.axis;
         var isCategoryAxis = axis.type === 'category';
@@ -198,20 +237,31 @@ BaseAxisPointer.prototype = {
         }
 
         return animation === true;
-    },
+    }
 
     /**
      * add {pointer, label, graphicKey} to elOption
      * @protected
      */
-    makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
+    makeElOption(
+        elOption: AxisPointerElementOptions,
+        value: AxisValue,
+        axisModel: AxisBaseModel,
+        axisPointerModel: AxisPointerModel,
+        api: ExtensionAPI
+    ) {
         // Shoule be implemenented by sub-class.
-    },
+    }
 
     /**
      * @protected
      */
-    createPointerEl: function (group, elOption, axisModel, axisPointerModel) {
+    createPointerEl(
+        group: graphic.Group,
+        elOption: AxisPointerElementOptions,
+        axisModel: AxisBaseModel,
+        axisPointerModel: AxisPointerModel
+    ) {
         var pointerOption = elOption.pointer;
         if (pointerOption) {
             var pointerEl = inner(group).pointerEl = new graphic[pointerOption.type](
@@ -219,12 +269,17 @@ BaseAxisPointer.prototype = {
             );
             group.add(pointerEl);
         }
-    },
+    }
 
     /**
      * @protected
      */
-    createLabelEl: function (group, elOption, axisModel, axisPointerModel) {
+    createLabelEl(
+        group: graphic.Group,
+        elOption: AxisPointerElementOptions,
+        axisModel: AxisBaseModel,
+        axisPointerModel: AxisPointerModel
+    ) {
         if (elOption.label) {
             var labelEl = inner(group).labelEl = new graphic.Rect(
                 clone(elOption.label)
@@ -233,23 +288,32 @@ BaseAxisPointer.prototype = {
             group.add(labelEl);
             updateLabelShowHide(labelEl, axisPointerModel);
         }
-    },
+    }
 
     /**
      * @protected
      */
-    updatePointerEl: function (group, elOption, updateProps) {
+    updatePointerEl(
+        group: graphic.Group,
+        elOption: AxisPointerElementOptions,
+        updateProps: (el: Element, props: PathProps) => void
+    ) {
         var pointerEl = inner(group).pointerEl;
         if (pointerEl && elOption.pointer) {
             pointerEl.setStyle(elOption.pointer.style);
             updateProps(pointerEl, {shape: elOption.pointer.shape});
         }
-    },
+    }
 
     /**
      * @protected
      */
-    updateLabelEl: function (group, elOption, updateProps, axisPointerModel) {
+    updateLabelEl(
+        group: graphic.Group,
+        elOption: AxisPointerElementOptions,
+        updateProps: (el: Element, props: PathProps) => void,
+        axisPointerModel: AxisPointerModel
+    ) {
         var labelEl = inner(group).labelEl;
         if (labelEl) {
             labelEl.setStyle(elOption.label.style);
@@ -262,12 +326,12 @@ BaseAxisPointer.prototype = {
 
             updateLabelShowHide(labelEl, axisPointerModel);
         }
-    },
+    }
 
     /**
      * @private
      */
-    _renderHandle: function (value) {
+    _renderHandle(value: AxisValue) {
         if (this._dragging || !this.updateHandleTransform) {
             return;
         }
@@ -292,7 +356,7 @@ BaseAxisPointer.prototype = {
                 {
                     cursor: 'move',
                     draggable: true,
-                    onmousemove: function (e) {
+                    onmousemove(e) {
                         // Fot mobile devicem, prevent screen slider on the button.
                         eventTool.stop(e.event);
                     },
@@ -307,18 +371,17 @@ BaseAxisPointer.prototype = {
         updateMandatoryProps(handle, axisPointerModel, false);
 
         // update style
-        var includeStyles = [
+        handle.setStyle(handleModel.getItemStyle(null, [
             'color', 'borderColor', 'borderWidth', 'opacity',
             'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'
-        ];
-        handle.setStyle(handleModel.getItemStyle(null, includeStyles));
+        ]));
 
         // update position
         var handleSize = handleModel.get('size');
         if (!zrUtil.isArray(handleSize)) {
             handleSize = [handleSize, handleSize];
         }
-        handle.attr('scale', [handleSize[0] / 2, handleSize[1] / 2]);
+        (handle as graphic.Path).attr('scale', [handleSize[0] / 2, handleSize[1] / 2]);
 
         throttleUtil.createOrUpdate(
             this,
@@ -328,12 +391,12 @@ BaseAxisPointer.prototype = {
         );
 
         this._moveHandleToValue(value, isInit);
-    },
+    }
 
     /**
      * @private
      */
-    _moveHandleToValue: function (value, isInit) {
+    _moveHandleToValue(value: AxisValue, isInit?: boolean) {
         updateProps(
             this._axisPointerModel,
             !isInit && this._moveAnimation,
@@ -342,12 +405,12 @@ BaseAxisPointer.prototype = {
                 value, this._axisModel, this._axisPointerModel
             ))
         );
-    },
+    }
 
     /**
      * @private
      */
-    _onHandleDragMove: function (dx, dy) {
+    _onHandleDragMove(dx: number, dy: number) {
         var handle = this._handle;
         if (!handle) {
             return;
@@ -365,17 +428,17 @@ BaseAxisPointer.prototype = {
         this._payloadInfo = trans;
 
         handle.stopAnimation();
-        handle.attr(getHandleTransProps(trans));
+        (handle as graphic.Path).attr(getHandleTransProps(trans));
         inner(handle).lastProp = null;
 
         this._doDispatchAxisPointer();
-    },
+    }
 
     /**
      * Throttled method.
      * @private
      */
-    _doDispatchAxisPointer: function () {
+    _doDispatchAxisPointer() {
         var handle = this._handle;
         if (!handle) {
             return;
@@ -393,12 +456,12 @@ BaseAxisPointer.prototype = {
                 axisIndex: axisModel.componentIndex
             }]
         });
-    },
+    }
 
     /**
      * @private
      */
-    _onHandleDragEnd: function (moveAnimation) {
+    _onHandleDragEnd() {
         this._dragging = false;
         var handle = this._handle;
         if (!handle) {
@@ -416,33 +479,12 @@ BaseAxisPointer.prototype = {
         this._api.dispatchAction({
             type: 'hideTip'
         });
-    },
-
-    /**
-     * Should be implemenented by sub-class if support `handle`.
-     * @protected
-     * @param {number} value
-     * @param {module:echarts/model/Model} axisModel
-     * @param {module:echarts/model/Model} axisPointerModel
-     * @return {Object} {position: [x, y], rotation: 0}
-     */
-    getHandleTransform: null,
-
-    /**
-     * * Should be implemenented by sub-class if support `handle`.
-     * @protected
-     * @param {Object} transform {position, rotation}
-     * @param {Array.<number>} delta [dx, dy]
-     * @param {module:echarts/model/Model} axisModel
-     * @param {module:echarts/model/Model} axisPointerModel
-     * @return {Object} {position: [x, y], rotation: 0, cursorPoint: [x, y]}
-     */
-    updateHandleTransform: null,
+    }
 
     /**
      * @private
      */
-    clear: function (api) {
+    clear(api: ExtensionAPI) {
         this._lastValue = null;
         this._lastStatus = null;
 
@@ -457,22 +499,16 @@ BaseAxisPointer.prototype = {
             this._handle = null;
             this._payloadInfo = null;
         }
-    },
+    }
 
     /**
      * @protected
      */
-    doClear: function () {
+    doClear() {
         // Implemented by sub-class if necessary.
-    },
+    }
 
-    /**
-     * @protected
-     * @param {Array.<number>} xy
-     * @param {Array.<number>} wh
-     * @param {number} [xDimIndex=0] or 1
-     */
-    buildLabel: function (xy, wh, xDimIndex) {
+    buildLabel(xy: number[], wh: number[], xDimIndex: 0 | 1) {
         xDimIndex = xDimIndex || 0;
         return {
             x: xy[xDimIndex],
@@ -481,22 +517,28 @@ BaseAxisPointer.prototype = {
             height: wh[1 - xDimIndex]
         };
     }
-};
-
-BaseAxisPointer.prototype.constructor = BaseAxisPointer;
+}
 
 
-function updateProps(animationModel, moveAnimation, el, props) {
+function updateProps(
+    animationModel: AxisPointerModel,
+    moveAnimation: boolean,
+    el: Element,
+    props: DisplayableProps
+) {
     // Animation optimize.
     if (!propsEqual(inner(el).lastProp, props)) {
         inner(el).lastProp = props;
         moveAnimation
-            ? graphic.updateProps(el, props, animationModel)
+            ? graphic.updateProps(el, props, animationModel as Model<
+                // Ignore animation property
+                Pick<CommonAxisPointerOption, 'animationDurationUpdate' | 'animationEasingUpdate'>
+            >)
             : (el.stopAnimation(), el.attr(props));
     }
 }
 
-function propsEqual(lastProps, newProps) {
+function propsEqual(lastProps: any, newProps: any) {
     if (zrUtil.isObject(lastProps) && zrUtil.isObject(newProps)) {
         var equals = true;
         zrUtil.each(newProps, function (item, key) {
@@ -509,22 +551,26 @@ function propsEqual(lastProps, newProps) {
     }
 }
 
-function updateLabelShowHide(labelEl, axisPointerModel) {
-    labelEl[axisPointerModel.get('label.show') ? 'show' : 'hide']();
+function updateLabelShowHide(labelEl: Element, axisPointerModel: AxisPointerModel) {
+    labelEl[axisPointerModel.get(['label', 'show']) ? 'show' : 'hide']();
 }
 
-function getHandleTransProps(trans) {
+function getHandleTransProps(trans: Transform): Transform {
     return {
         position: trans.position.slice(),
         rotation: trans.rotation || 0
     };
 }
 
-function updateMandatoryProps(group, axisPointerModel, silent) {
+function updateMandatoryProps(
+    group: Element,
+    axisPointerModel: AxisPointerModel,
+    silent?: boolean
+) {
     var z = axisPointerModel.get('z');
     var zlevel = axisPointerModel.get('zlevel');
 
-    group && group.traverse(function (el) {
+    group && group.traverse(function (el: Displayable) {
         if (el.type !== 'group') {
             z != null && (el.z = z);
             zlevel != null && (el.zlevel = zlevel);
@@ -533,6 +579,4 @@ function updateMandatoryProps(group, axisPointerModel, silent) {
     });
 }
 
-clazzUtil.enableClassExtend(BaseAxisPointer);
-
 export default BaseAxisPointer;
\ No newline at end of file
diff --git a/src/component/axisPointer/CartesianAxisPointer.ts b/src/component/axisPointer/CartesianAxisPointer.ts
index de25742..1644e69 100644
--- a/src/component/axisPointer/CartesianAxisPointer.ts
+++ b/src/component/axisPointer/CartesianAxisPointer.ts
@@ -17,19 +17,34 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import BaseAxisPointer from './BaseAxisPointer';
+import BaseAxisPointer, {AxisPointerElementOptions} from './BaseAxisPointer';
 import * as viewHelper from './viewHelper';
 import * as cartesianAxisHelper from '../../coord/cartesian/cartesianAxisHelper';
 import AxisView from '../axis/AxisView';
+import CartesianAxisModel from '../../coord/cartesian/AxisModel';
+import ExtensionAPI from '../../ExtensionAPI';
+import { ScaleDataValue, VerticalAlign, HorizontalAlign, CommonAxisPointerOption } from '../../util/types';
+import Grid from '../../coord/cartesian/Grid';
+import Axis2D from '../../coord/cartesian/Axis2D';
+import { PathProps } from 'zrender/src/graphic/Path';
+import { VectorArray } from 'zrender/src/core/vector';
+import Model from '../../model/Model';
+
+// Not use top level axisPointer model
+type AxisPointerModel = Model<CommonAxisPointerOption>
 
-var CartesianAxisPointer = BaseAxisPointer.extend({
+class CartesianAxisPointer extends BaseAxisPointer {
 
     /**
      * @override
      */
-    makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
+    makeElOption(
+        elOption: AxisPointerElementOptions,
+        value: ScaleDataValue,
+        axisModel: CartesianAxisModel,
+        axisPointerModel: AxisPointerModel,
+        api: ExtensionAPI
+    ) {
         var axis = axisModel.axis;
         var grid = axis.grid;
         var axisPointerType = axisPointerModel.get('type');
@@ -48,28 +63,43 @@ var CartesianAxisPointer = BaseAxisPointer.extend({
 
         var layoutInfo = cartesianAxisHelper.layout(grid.model, axisModel);
         viewHelper.buildCartesianSingleLabelElOption(
+            // @ts-ignore
             value, elOption, layoutInfo, axisModel, axisPointerModel, api
         );
-    },
+    }
 
     /**
      * @override
      */
-    getHandleTransform: function (value, axisModel, axisPointerModel) {
+    getHandleTransform(
+        value: ScaleDataValue,
+        axisModel: CartesianAxisModel,
+        axisPointerModel: AxisPointerModel
+    ) {
         var layoutInfo = cartesianAxisHelper.layout(axisModel.axis.grid.model, axisModel, {
             labelInside: false
         });
-        layoutInfo.labelMargin = axisPointerModel.get('handle.margin');
+        // @ts-ignore
+        layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
         return {
+            // @ts-ignore
             position: viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo),
             rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
         };
-    },
+    }
 
     /**
      * @override
      */
-    updateHandleTransform: function (transform, delta, axisModel, axisPointerModel) {
+    updateHandleTransform(
+        transform: {
+            position: VectorArray,
+            rotation: number
+        },
+        delta: number[],
+        axisModel: CartesianAxisModel,
+        axisPointerModel: AxisPointerModel
+    ) {
         var axis = axisModel.axis;
         var grid = axis.grid;
         var axisExtent = axis.getGlobalExtent(true);
@@ -86,7 +116,13 @@ var CartesianAxisPointer = BaseAxisPointer.extend({
         cursorPoint[dimIndex] = currPosition[dimIndex];
 
         // Make tooltip do not overlap axisPointer and in the middle of the grid.
-        var tooltipOptions = [{verticalAlign: 'middle'}, {align: 'center'}];
+        var tooltipOptions: {
+            verticalAlign?: VerticalAlign
+            align?: HorizontalAlign
+        }[] = [
+            {verticalAlign: 'middle'},
+            {align: 'center'}
+        ];
 
         return {
             position: currPosition,
@@ -95,18 +131,20 @@ var CartesianAxisPointer = BaseAxisPointer.extend({
             tooltipOption: tooltipOptions[dimIndex]
         };
     }
+}
 
-});
-
-function getCartesian(grid, axis) {
-    var opt = {};
-    opt[axis.dim + 'AxisIndex'] = axis.index;
+function getCartesian(grid: Grid, axis: Axis2D) {
+    var opt = {} as {
+        xAxisIndex?: number
+        yAxisIndex?: number
+    };
+    opt[axis.dim + 'AxisIndex' as 'xAxisIndex' | 'yAxisIndex'] = axis.index;
     return grid.getCartesian(opt);
 }
 
 var pointerShapeBuilder = {
 
-    line: function (axis, pixelValue, otherExtent) {
+    line: function (axis: Axis2D, pixelValue: number, otherExtent: number[]): PathProps & { type: 'Line'} {
         var targetShape = viewHelper.makeLineShape(
             [pixelValue, otherExtent[0]],
             [pixelValue, otherExtent[1]],
@@ -119,7 +157,7 @@ var pointerShapeBuilder = {
         };
     },
 
-    shadow: function (axis, pixelValue, otherExtent) {
+    shadow: function (axis: Axis2D, pixelValue: number, otherExtent: number[]): PathProps & { type: 'Rect'} {
         var bandWidth = Math.max(1, axis.getBandWidth());
         var span = otherExtent[1] - otherExtent[0];
         return {
@@ -133,10 +171,11 @@ var pointerShapeBuilder = {
     }
 };
 
-function getAxisDimIndex(axis) {
+function getAxisDimIndex(axis: Axis2D) {
     return axis.dim === 'x' ? 0 : 1;
 }
 
+// @ts-ignore
 AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer);
 
 export default CartesianAxisPointer;
\ No newline at end of file
diff --git a/src/component/axisPointer/PolarAxisPointer.ts b/src/component/axisPointer/PolarAxisPointer.ts
index 72d6f32..4760706 100644
--- a/src/component/axisPointer/PolarAxisPointer.ts
+++ b/src/component/axisPointer/PolarAxisPointer.ts
@@ -17,23 +17,36 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import * as formatUtil from '../../util/format';
-import BaseAxisPointer from './BaseAxisPointer';
+import BaseAxisPointer, { AxisPointerElementOptions } from './BaseAxisPointer';
 import * as graphic from '../../util/graphic';
 import * as viewHelper from './viewHelper';
 import * as matrix from 'zrender/src/core/matrix';
 import AxisBuilder from '../axis/AxisBuilder';
 import AxisView from '../axis/AxisView';
+import { OptionDataValue, ScaleDataValue, CommonAxisPointerOption } from '../../util/types';
+import { PolarAxisModel } from '../../coord/polar/AxisModel';
+import ExtensionAPI from '../../ExtensionAPI';
+import Polar from '../../coord/polar/Polar';
+import AngleAxis from '../../coord/polar/AngleAxis';
+import RadiusAxis from '../../coord/polar/RadiusAxis';
+import { PathProps } from 'zrender/src/graphic/Path';
+import Model from '../../model/Model';
 
+// Not use top level axisPointer model
+type AxisPointerModel = Model<CommonAxisPointerOption>
 
-var PolarAxisPointer = BaseAxisPointer.extend({
+class PolarAxisPointer extends BaseAxisPointer {
 
     /**
      * @override
      */
-    makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
+    makeElOption(
+        elOption: AxisPointerElementOptions,
+        value: OptionDataValue,
+        axisModel: PolarAxisModel,
+        axisPointerModel: Model<CommonAxisPointerOption>,
+        api: ExtensionAPI
+    ) {
         var axis = axisModel.axis;
 
         if (axis.dim === 'angle') {
@@ -45,29 +58,35 @@ var PolarAxisPointer = BaseAxisPointer.extend({
         var otherExtent = otherAxis.getExtent();
 
         var coordValue;
-        coordValue = axis['dataTo' + formatUtil.capitalFirst(axis.dim)](value);
+        coordValue = axis.dataToCoord(value);
 
         var axisPointerType = axisPointerModel.get('type');
         if (axisPointerType && axisPointerType !== 'none') {
             var elStyle = viewHelper.buildElStyle(axisPointerModel);
             var pointerOption = pointerShapeBuilder[axisPointerType](
-                axis, polar, coordValue, otherExtent, elStyle
+                axis, polar, coordValue, otherExtent
             );
             pointerOption.style = elStyle;
             elOption.graphicKey = pointerOption.type;
             elOption.pointer = pointerOption;
         }
 
-        var labelMargin = axisPointerModel.get('label.margin');
+        var labelMargin = axisPointerModel.get(['label', 'margin']);
         var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin);
         viewHelper.buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos);
     }
 
     // Do not support handle, utill any user requires it.
 
-});
+};
 
-function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) {
+function getLabelPosition(
+    value: ScaleDataValue,
+    axisModel: PolarAxisModel,
+    axisPointerModel: AxisPointerModel,
+    polar: Polar,
+    labelMargin: number
+) {
     var axis = axisModel.axis;
     var coord = axis.dataToCoord(value);
     var axisAngle = polar.getAngleAxis().getExtent()[0];
@@ -84,6 +103,7 @@ function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin
         position = graphic.applyTransform([coord, -labelMargin], transform);
 
         var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0;
+        // @ts-ignore
         var labelLayout = AxisBuilder.innerTextLayout(
             axisAngle, labelRotation * Math.PI / 180, -1
         );
@@ -111,7 +131,12 @@ function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin
 
 var pointerShapeBuilder = {
 
-    line: function (axis, polar, coordValue, otherExtent, elStyle) {
+    line: function (
+        axis: AngleAxis | RadiusAxis,
+        polar: Polar,
+        coordValue: number,
+        otherExtent: number[]
+    ): PathProps & { type: 'Line' | 'Circle' } {
         return axis.dim === 'angle'
             ? {
                 type: 'Line',
@@ -130,7 +155,12 @@ var pointerShapeBuilder = {
             };
     },
 
-    shadow: function (axis, polar, coordValue, otherExtent, elStyle) {
+    shadow: function (
+        axis: AngleAxis | RadiusAxis,
+        polar: Polar,
+        coordValue: number,
+        otherExtent: number[]
+    ): PathProps & { type: 'Sector' } {
         var bandWidth = Math.max(1, axis.getBandWidth());
         var radian = Math.PI / 180;
 
@@ -157,6 +187,7 @@ var pointerShapeBuilder = {
     }
 };
 
+// @ts-ignore
 AxisView.registerAxisPointerClass('PolarAxisPointer', PolarAxisPointer);
 
 export default PolarAxisPointer;
\ No newline at end of file
diff --git a/src/component/axisPointer/SingleAxisPointer.ts b/src/component/axisPointer/SingleAxisPointer.ts
index 06625a8..2037823 100644
--- a/src/component/axisPointer/SingleAxisPointer.ts
+++ b/src/component/axisPointer/SingleAxisPointer.ts
@@ -17,22 +17,37 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import BaseAxisPointer from './BaseAxisPointer';
+import BaseAxisPointer, { AxisPointerElementOptions } from './BaseAxisPointer';
 import * as viewHelper from './viewHelper';
 import * as singleAxisHelper from '../../coord/single/singleAxisHelper';
 import AxisView from '../axis/AxisView';
+import SingleAxis from '../../coord/single/SingleAxis';
+import Single from '../../coord/single/Single';
+import { PathProps } from 'zrender/src/graphic/Path';
+import { ScaleDataValue, VerticalAlign, CommonAxisPointerOption } from '../../util/types';
+import ExtensionAPI from '../../ExtensionAPI';
+import SingleAxisModel from '../../coord/single/AxisModel';
+import { VectorArray } from 'zrender/src/core/vector';
+import Model from '../../model/Model';
+
+const XY = ['x', 'y'] as const;
+const WH = ['width', 'height'] as const;
 
-var XY = ['x', 'y'];
-var WH = ['width', 'height'];
+// Not use top level axisPointer model
+type AxisPointerModel = Model<CommonAxisPointerOption>
 
-var SingleAxisPointer = BaseAxisPointer.extend({
+class SingleAxisPointer extends BaseAxisPointer {
 
     /**
      * @override
      */
-    makeElOption: function (elOption, value, axisModel, axisPointerModel, api) {
+    makeElOption(
+        elOption: AxisPointerElementOptions,
+        value: ScaleDataValue,
+        axisModel: SingleAxisModel,
+        axisPointerModel: AxisPointerModel,
+        api: ExtensionAPI
+    ) {
         var axis = axisModel.axis;
         var coordSys = axis.coordinateSystem;
         var otherExtent = getGlobalExtent(coordSys, 1 - getPointDimIndex(axis));
@@ -52,26 +67,40 @@ var SingleAxisPointer = BaseAxisPointer.extend({
 
         var layoutInfo = singleAxisHelper.layout(axisModel);
         viewHelper.buildCartesianSingleLabelElOption(
+            // @ts-ignore
             value, elOption, layoutInfo, axisModel, axisPointerModel, api
         );
-    },
+    }
 
     /**
      * @override
      */
-    getHandleTransform: function (value, axisModel, axisPointerModel) {
+    getHandleTransform(
+        value: ScaleDataValue,
+        axisModel: SingleAxisModel,
+        axisPointerModel: AxisPointerModel
+    ) {
         var layoutInfo = singleAxisHelper.layout(axisModel, {labelInside: false});
-        layoutInfo.labelMargin = axisPointerModel.get('handle.margin');
+        // @ts-ignore
+        layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
         return {
             position: viewHelper.getTransformedPosition(axisModel.axis, value, layoutInfo),
             rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
         };
-    },
+    }
 
     /**
      * @override
      */
-    updateHandleTransform: function (transform, delta, axisModel, axisPointerModel) {
+    updateHandleTransform(
+        transform: {
+            position: VectorArray,
+            rotation: number
+        },
+        delta: number[],
+        axisModel: SingleAxisModel,
+        axisPointerModel: AxisPointerModel
+    ) {
         var axis = axisModel.axis;
         var coordSys = axis.coordinateSystem;
         var dimIndex = getPointDimIndex(axis);
@@ -90,15 +119,17 @@ var SingleAxisPointer = BaseAxisPointer.extend({
             rotation: transform.rotation,
             cursorPoint: cursorPoint,
             tooltipOption: {
-                verticalAlign: 'middle'
+                verticalAlign: 'middle' as VerticalAlign
             }
         };
     }
-});
+}
 
 var pointerShapeBuilder = {
 
-    line: function (axis, pixelValue, otherExtent) {
+    line: function (axis: SingleAxis, pixelValue: number, otherExtent: number[]): PathProps & {
+        type: 'Line'
+    } {
         var targetShape = viewHelper.makeLineShape(
             [pixelValue, otherExtent[0]],
             [pixelValue, otherExtent[1]],
@@ -111,7 +142,9 @@ var pointerShapeBuilder = {
         };
     },
 
-    shadow: function (axis, pixelValue, otherExtent) {
+    shadow: function (axis: SingleAxis, pixelValue: number, otherExtent: number[]): PathProps & {
+        type: 'Rect'
+    } {
         var bandWidth = axis.getBandWidth();
         var span = otherExtent[1] - otherExtent[0];
         return {
@@ -125,15 +158,16 @@ var pointerShapeBuilder = {
     }
 };
 
-function getPointDimIndex(axis) {
+function getPointDimIndex(axis: SingleAxis): number {
     return axis.isHorizontal() ? 0 : 1;
 }
 
-function getGlobalExtent(coordSys, dimIndex) {
+function getGlobalExtent(coordSys: Single, dimIndex: number) {
     var rect = coordSys.getRect();
     return [rect[XY[dimIndex]], rect[XY[dimIndex]] + rect[WH[dimIndex]]];
 }
 
+// @ts-ignore
 AxisView.registerAxisPointerClass('SingleAxisPointer', SingleAxisPointer);
 
 export default SingleAxisPointer;
\ No newline at end of file
diff --git a/src/component/axisPointer/axisTrigger.ts b/src/component/axisPointer/axisTrigger.ts
index 8536235..2f77710 100644
--- a/src/component/axisPointer/axisTrigger.ts
+++ b/src/component/axisPointer/axisTrigger.ts
@@ -17,50 +17,107 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import * as zrUtil from 'zrender/src/core/util';
-import {makeInner} from '../../util/model';
+import {makeInner, ModelFinderObject} from '../../util/model';
 import * as modelHelper from './modelHelper';
 import findPointFromSeries from './findPointFromSeries';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { Dictionary, Payload, CommonAxisPointerOption } from '../../util/types';
+import AxisPointerModel, { AxisPointerOption } from './AxisPointerModel';
+import { each, curry, bind, extend, Curry1 } from 'zrender/src/core/util';
+
+var inner = makeInner<{
+    axisPointerLastHighlights: Dictionary<BatchItem>
+}>();
+
+type AxisValue = CommonAxisPointerOption['value'];
+
+interface DataIndex {
+    seriesIndex: number
+    dataIndex: number
+    dataIndexInside: number
+}
+
+type BatchItem = DataIndex;
+
+interface DataByAxis {
+    // TODO: TYPE Value type
+    value: string | number
+    axisIndex: number
+    axisDim: string
+    axisType: string
+    axisId: string
+
+    seriesDataIndices: DataIndex[]
+
+    valueLabelOpt: {
+        precision: AxisPointerOption['label']['precision']
+        formatter: AxisPointerOption['label']['formatter']
+    }
+}
+interface DataByCoordSys {
+    coordSysId: string
+    coordSysIndex: number
+    coordSysType: string
+    coordSysMainType: string
+    dataByAxis: DataByAxis[]
+}
+interface DataByCoordSysCollection {
+    list: DataByCoordSys[]
+    map: Dictionary<DataByCoordSys>
+}
+
+type CollectedCoordInfo = ReturnType<typeof modelHelper['collect']>
+type CollectedAxisInfo = CollectedCoordInfo['axesInfo'][string]
+
+interface AxisTriggerPayload extends Payload {
+    currTrigger?: 'click' | 'mousemove' | 'leave'
+    /**
+     * x and y, which are mandatory, specify a point to trigger axisPointer and tooltip.
+     */
+    x?: number
+    /**
+     * x and y, which are mandatory, specify a point to trigger axisPointer and tooltip.
+     */
+    y?: number
+    /**
+     * finder, optional, restrict target axes.
+     */
+    seriesIndex?: number
+    dataIndex: number
+
+    axesInfo?: {
+        // 'x'|'y'|'angle'
+        axisDim?: string
+        axisIndex?: number
+        value?: AxisValue
+    }[]
+
+    dispatchAction: ExtensionAPI['dispatchAction']
+}
 
-var each = zrUtil.each;
-var curry = zrUtil.curry;
-var inner = makeInner();
+type ShowValueMap = Dictionary<{
+    value: AxisValue
+    payloadBatch: BatchItem[]
+}>
 
 /**
  * Basic logic: check all axis, if they do not demand show/highlight,
  * then hide/downplay them.
  *
- * @param {Object} coordSysAxesInfo
- * @param {Object} payload
- * @param {string} [payload.currTrigger] 'click' | 'mousemove' | 'leave'
- * @param {Array.<number>} [payload.x] x and y, which are mandatory, specify a point to
- *              trigger axisPointer and tooltip.
- * @param {Array.<number>} [payload.y] x and y, which are mandatory, specify a point to
- *              trigger axisPointer and tooltip.
- * @param {Object} [payload.seriesIndex] finder, optional, restrict target axes.
- * @param {Object} [payload.dataIndex] finder, restrict target axes.
- * @param {Object} [payload.axesInfo] finder, restrict target axes.
- *        [{
- *          axisDim: 'x'|'y'|'angle'|...,
- *          axisIndex: ...,
- *          value: ...
- *        }, ...]
- * @param {Function} [payload.dispatchAction]
- * @param {Object} [payload.tooltipOption]
- * @param {Object|Array.<number>|Function} [payload.position] Tooltip position,
- *        which can be specified in dispatchAction
- * @param {module:echarts/model/Global} ecModel
- * @param {module:echarts/ExtensionAPI} api
- * @return {Object} content of event obj for echarts.connect.
+ * @return content of event obj for echarts.connect.
  */
-export default function (payload, ecModel, api) {
+export default function (
+    payload: AxisTriggerPayload,
+    ecModel: GlobalModel,
+    api: ExtensionAPI
+) {
     var currTrigger = payload.currTrigger;
     var point = [payload.x, payload.y];
     var finder = payload;
-    var dispatchAction = payload.dispatchAction || zrUtil.bind(api.dispatchAction, api);
-    var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;
+    var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api);
+    var coordSysAxesInfo = (ecModel.getComponent('axisPointer') as AxisPointerModel)
+        .coordSysAxesInfo as CollectedCoordInfo;
 
     // Pending
     // See #6121. But we are not able to reproduce it yet.
@@ -88,10 +145,13 @@ export default function (payload, ecModel, api) {
 
     var axesInfo = coordSysAxesInfo.axesInfo;
     var shouldHide = currTrigger === 'leave' || illegalPoint(point);
-    var outputFinder = {};
+    var outputPayload = {} as AxisTriggerPayload;
 
-    var showValueMap = {};
-    var dataByCoordSys = {list: [], map: {}};
+    var showValueMap: ShowValueMap = {};
+    var dataByCoordSys: DataByCoordSysCollection = {
+        list: [],
+        map: {}
+    };
     var updaters = {
         showPointer: curry(showPointer, showValueMap),
         showTooltip: curry(showTooltip, dataByCoordSys)
@@ -111,13 +171,13 @@ export default function (payload, ecModel, api) {
                 if (val == null && !isIllegalPoint) {
                     val = axis.pointToData(point);
                 }
-                val != null && processOnAxis(axisInfo, val, updaters, false, outputFinder);
+                val != null && processOnAxis(axisInfo, val, updaters, false, outputPayload);
             }
         });
     });
 
     // Process for linked axes.
-    var linkTriggers = {};
+    var linkTriggers: Dictionary<AxisValue> = {};
     each(axesInfo, function (tarAxisInfo, tarKey) {
         var linkGroup = tarAxisInfo.linkGroup;
 
@@ -137,17 +197,26 @@ export default function (payload, ecModel, api) {
         }
     });
     each(linkTriggers, function (val, tarKey) {
-        processOnAxis(axesInfo[tarKey], val, updaters, true, outputFinder);
+        processOnAxis(axesInfo[tarKey], val, updaters, true, outputPayload);
     });
 
-    updateModelActually(showValueMap, axesInfo, outputFinder);
+    updateModelActually(showValueMap, axesInfo, outputPayload);
     dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction);
     dispatchHighDownActually(axesInfo, dispatchAction, api);
 
-    return outputFinder;
+    return outputPayload;
 }
 
-function processOnAxis(axisInfo, newValue, updaters, dontSnap, outputFinder) {
+function processOnAxis(
+    axisInfo: CollectedCoordInfo['axesInfo'][string],
+    newValue: AxisValue,
+    updaters: {
+        showPointer: Curry1<typeof showPointer, ShowValueMap>
+        showTooltip: Curry1<typeof showTooltip, DataByCoordSysCollection>
+    },
+    noSnap: boolean,
+    outputFinder: ModelFinderObject
+) {
     var axis = axisInfo.axis;
 
     if (axis.scale.isBlank() || !axis.containData(newValue)) {
@@ -167,28 +236,28 @@ function processOnAxis(axisInfo, newValue, updaters, dontSnap, outputFinder) {
     // Fill content of event obj for echarts.connect.
     // By defualt use the first involved series data as a sample to connect.
     if (payloadBatch[0] && outputFinder.seriesIndex == null) {
-        zrUtil.extend(outputFinder, payloadBatch[0]);
+        extend(outputFinder, payloadBatch[0]);
     }
 
     // If no linkSource input, this process is for collecting link
     // target, where snap should not be accepted.
-    if (!dontSnap && axisInfo.snap) {
+    if (!noSnap && axisInfo.snap) {
         if (axis.containData(snapToValue) && snapToValue != null) {
             newValue = snapToValue;
         }
     }
 
-    updaters.showPointer(axisInfo, newValue, payloadBatch, outputFinder);
+    updaters.showPointer(axisInfo, newValue, payloadBatch);
     // Tooltip should always be snapToValue, otherwise there will be
     // incorrect "axis value ~ series value" mapping displayed in tooltip.
     updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
 }
 
-function buildPayloadsBySeries(value, axisInfo) {
+function buildPayloadsBySeries(value: AxisValue, axisInfo: CollectedAxisInfo) {
     var axis = axisInfo.axis;
     var dim = axis.dim;
     var snapToValue = value;
-    var payloadBatch = [];
+    var payloadBatch: BatchItem[] = [];
     var minDist = Number.MAX_VALUE;
     var minDiff = -1;
 
@@ -247,11 +316,24 @@ function buildPayloadsBySeries(value, axisInfo) {
     };
 }
 
-function showPointer(showValueMap, axisInfo, value, payloadBatch) {
-    showValueMap[axisInfo.key] = {value: value, payloadBatch: payloadBatch};
+function showPointer(
+    showValueMap: ShowValueMap,
+    axisInfo: CollectedAxisInfo,
+    value: AxisValue,
+    payloadBatch?: BatchItem[]
+) {
+    showValueMap[axisInfo.key] = {
+        value: value,
+        payloadBatch: payloadBatch
+    };
 }
 
-function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
+function showTooltip(
+    dataByCoordSys: DataByCoordSysCollection,
+    axisInfo: CollectedCoordInfo['axesInfo'][string],
+    payloadInfo: { payloadBatch: BatchItem[] },
+    value: AxisValue
+) {
     var payloadBatch = payloadInfo.payloadBatch;
     var axis = axisInfo.axis;
     var axisModel = axis.model;
@@ -288,15 +370,19 @@ function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
         // here. Considering axisPointerModel used here is volatile, which is hard
         // to be retrieve in TooltipView, we prepare parameters here.
         valueLabelOpt: {
-            precision: axisPointerModel.get('label.precision'),
-            formatter: axisPointerModel.get('label.formatter')
+            precision: axisPointerModel.get(['label', 'precision']),
+            formatter: axisPointerModel.get(['label', 'formatter'])
         },
         seriesDataIndices: payloadBatch.slice()
     });
 }
 
-function updateModelActually(showValueMap, axesInfo, outputFinder) {
-    var outputAxesInfo = outputFinder.axesInfo = [];
+function updateModelActually(
+    showValueMap: ShowValueMap,
+    axesInfo: Dictionary<CollectedAxisInfo>,
+    outputPayload: AxisTriggerPayload
+) {
+    var outputAxesInfo: AxisTriggerPayload['axesInfo'] = outputPayload.axesInfo = [];
     // Basic logic: If no 'show' required, 'hide' this axisPointer.
     each(axesInfo, function (axisInfo, key) {
         var option = axisInfo.axisPointerModel.option;
@@ -325,7 +411,12 @@ function updateModelActually(showValueMap, axesInfo, outputFinder) {
     });
 }
 
-function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) {
+function dispatchTooltipActually(
+    dataByCoordSys: DataByCoordSysCollection,
+    point: number[],
+    payload: AxisTriggerPayload,
+    dispatchAction: ExtensionAPI['dispatchAction']
+) {
     // Basic logic: If no showTip required, hideTip will be dispatched.
     if (illegalPoint(point) || !dataByCoordSys.list.length) {
         dispatchAction({type: 'hideTip'});
@@ -336,7 +427,7 @@ function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction)
     // convinient to fetch payload.seriesIndex and payload.dataIndex
     // dirtectly. So put the first seriesIndex and dataIndex of the first
     // axis on the payload.
-    var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {};
+    var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {} as DataIndex;
 
     dispatchAction({
         type: 'showTip',
@@ -352,15 +443,19 @@ function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction)
     });
 }
 
-function dispatchHighDownActually(axesInfo, dispatchAction, api) {
+function dispatchHighDownActually(
+    axesInfo: Dictionary<CollectedAxisInfo>,
+    dispatchAction: ExtensionAPI['dispatchAction'],
+    api: ExtensionAPI
+) {
     // FIXME
     // highlight status modification shoule be a stage of main process?
     // (Consider confilct (e.g., legend and axisPointer) and setOption)
 
     var zr = api.getZr();
-    var highDownKey = 'axisPointerLastHighlights';
+    var highDownKey = 'axisPointerLastHighlights' as const;
     var lastHighlights = inner(zr)[highDownKey] || {};
-    var newHighlights = inner(zr)[highDownKey] = {};
+    var newHighlights: Dictionary<BatchItem> = inner(zr)[highDownKey] = {};
 
     // Update highlight/downplay status according to axisPointer model.
     // Build hash map and remove duplicate incidentally.
@@ -373,12 +468,12 @@ function dispatchHighDownActually(axesInfo, dispatchAction, api) {
     });
 
     // Diff.
-    var toHighlight = [];
-    var toDownplay = [];
-    zrUtil.each(lastHighlights, function (batchItem, key) {
+    var toHighlight: BatchItem[] = [];
+    var toDownplay: BatchItem[] = [];
+    each(lastHighlights, function (batchItem, key) {
         !newHighlights[key] && toDownplay.push(batchItem);
     });
-    zrUtil.each(newHighlights, function (batchItem, key) {
+    each(newHighlights, function (batchItem, key) {
         !lastHighlights[key] && toHighlight.push(batchItem);
     });
 
@@ -390,7 +485,10 @@ function dispatchHighDownActually(axesInfo, dispatchAction, api) {
     });
 }
 
-function findInputAxisInfo(inputAxesInfo, axisInfo) {
+function findInputAxisInfo(
+    inputAxesInfo: AxisTriggerPayload['axesInfo'],
+    axisInfo: CollectedAxisInfo
+) {
     for (var i = 0; i < (inputAxesInfo || []).length; i++) {
         var inputAxisInfo = inputAxesInfo[i];
         if (axisInfo.axis.dim === inputAxisInfo.axisDim
@@ -401,16 +499,22 @@ function findInputAxisInfo(inputAxesInfo, axisInfo) {
     }
 }
 
-function makeMapperParam(axisInfo) {
+function makeMapperParam(axisInfo: CollectedAxisInfo) {
     var axisModel = axisInfo.axis.model;
-    var item = {};
+    var item = {} as {
+        axisDim: string
+        axisIndex: number
+        axisId: string
+        axisName: string
+        // TODO `dim`AxisIndex, `dim`AxisName, `dim`AxisId?
+    };
     var dim = item.axisDim = axisInfo.axis.dim;
-    item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex;
-    item.axisName = item[dim + 'AxisName'] = axisModel.name;
-    item.axisId = item[dim + 'AxisId'] = axisModel.id;
+    item.axisIndex = (item as any)[dim + 'AxisIndex'] = axisModel.componentIndex;
+    item.axisName = (item as any)[dim + 'AxisName'] = axisModel.name;
+    item.axisId = (item as any)[dim + 'AxisId'] = axisModel.id;
     return item;
 }
 
-function illegalPoint(point) {
+function illegalPoint(point?: number[]) {
     return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]);
 }
diff --git a/src/component/axisPointer/findPointFromSeries.ts b/src/component/axisPointer/findPointFromSeries.ts
index b48824d..a829454 100644
--- a/src/component/axisPointer/findPointFromSeries.ts
+++ b/src/component/axisPointer/findPointFromSeries.ts
@@ -17,28 +17,39 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import * as modelUtil from '../../util/model';
+import GlobalModel from '../../model/Global';
+import Element from 'zrender/src/Element';
+import { Payload } from '../../util/types';
 
 /**
- * @param {Object} finder contains {seriesIndex, dataIndex, dataIndexInside}
- * @param {module:echarts/model/Global} ecModel
- * @return {Object} {point: [x, y], el: ...} point Will not be null.
+ * @param finder contains {seriesIndex, dataIndex, dataIndexInside}
+ * @param ecModel
+ * @return  {point: [x, y], el: ...} point Will not be null.
  */
-export default function (finder, ecModel) {
-    var point = [];
+export default function (finder: {
+    seriesIndex?: number
+    dataIndex?: number | number[]
+    dataIndexInside?: number | number[]
+    name?: string | string[]
+}, ecModel: GlobalModel): {
+    point: number[]
+    el?: Element
+} {
+    var point: number[] = [];
     var seriesIndex = finder.seriesIndex;
     var seriesModel;
     if (seriesIndex == null || !(
         seriesModel = ecModel.getSeriesByIndex(seriesIndex)
     )) {
-        return {point: []};
+        return {
+            point: []
+        };
     }
 
     var data = seriesModel.getData();
-    var dataIndex = modelUtil.queryDataIndex(data, finder);
+    var dataIndex = modelUtil.queryDataIndex(data, finder as Payload);
     if (dataIndex == null || dataIndex < 0 || zrUtil.isArray(dataIndex)) {
         return {point: []};
     }
@@ -54,7 +65,7 @@ export default function (finder, ecModel) {
             data.getValues(
                 zrUtil.map(coordSys.dimensions, function (dim) {
                     return data.mapDimension(dim);
-                }), dataIndex, true
+                }), dataIndex
             )
         ) || [];
     }
diff --git a/src/component/axisPointer/modelHelper.ts b/src/component/axisPointer/modelHelper.ts
index 871480d..b8b4438 100644
--- a/src/component/axisPointer/modelHelper.ts
+++ b/src/component/axisPointer/modelHelper.ts
@@ -17,18 +17,69 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import * as zrUtil from 'zrender/src/core/util';
 import Model from '../../model/Model';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { each, curry, clone, defaults, isArray, indexOf } from 'zrender/src/core/util';
+import AxisPointerModel, { AxisPointerOption } from './AxisPointerModel';
+import Axis from '../../coord/Axis';
+import { TooltipOption } from '../tooltip/TooltipModel';
+import SeriesModel from '../../model/Series';
+import {
+    SeriesOption,
+    SeriesTooltipOption,
+    CommonAxisPointerOption,
+    Dictionary,
+    ComponentOption
+} from '../../util/types';
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
+import ComponentModel from '../../model/Component';
+import { CoordinateSystemMaster } from '../../coord/CoordinateSystem';
+
+interface LinkGroup {
+    mapper: AxisPointerOption['link'][number]['mapper']
+    /**
+     * { [axisKey]: AxisInfo }
+     */
+    axesInfo: Dictionary<AxisInfo>
+}
+interface AxisInfo {
+    axis: Axis
+    key: string
+    coordSys: CoordinateSystemMaster
+    axisPointerModel: Model<CommonAxisPointerOption>
+    triggerTooltip: boolean
+    involveSeries: boolean
+    snap: boolean
+    useHandle: boolean
+    seriesModels: SeriesModel[]
+
+    linkGroup?: LinkGroup
+    seriesDataCount?: number
+}
 
-var each = zrUtil.each;
-var curry = zrUtil.curry;
+interface CollectionResult {
+    /**
+     * { [coordSysKey]: { [axisKey]: AxisInfo } }
+     */
+    coordSysAxesInfo: Dictionary<Dictionary<AxisInfo>>
+
+    /**
+     * { [axisKey]: AxisInfo }
+     */
+    axesInfo: Dictionary<AxisInfo>
+    /**
+     * { [coordSysKey]: { CoordinateSystemMaster } }
+     */
+    coordSysMap: Dictionary<CoordinateSystemMaster>
+
+    seriesInvolved: boolean
+}
 
 // Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
 // allAxesInfo should be updated when setOption performed.
-export function collect(ecModel, api) {
-    var result = {
+export function collect(ecModel: GlobalModel, api: ExtensionAPI) {
+    var result: CollectionResult = {
         /**
          * key: makeKey(axis.model)
          * value: {
@@ -60,12 +111,12 @@ export function collect(ecModel, api) {
     return result;
 }
 
-function collectAxesInfo(result, ecModel, api) {
+function collectAxesInfo(result: CollectionResult, ecModel: GlobalModel, api: ExtensionAPI) {
     var globalTooltipModel = ecModel.getComponent('tooltip');
-    var globalAxisPointerModel = ecModel.getComponent('axisPointer');
+    var globalAxisPointerModel = ecModel.getComponent('axisPointer') as AxisPointerModel;
     // links can only be set on global.
     var linksOption = globalAxisPointerModel.get('link', true) || [];
-    var linkGroups = [];
+    var linkGroups: LinkGroup[] = [];
 
     // Collect axes info.
     each(api.getCoordinateSystems(), function (coordSys) {
@@ -75,12 +126,15 @@ function collectAxesInfo(result, ecModel, api) {
         }
 
         var coordSysKey = makeKey(coordSys.model);
-        var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
+        var axesInfoInCoordSys: CollectionResult['coordSysAxesInfo'][string] =
+            result.coordSysAxesInfo[coordSysKey] = {};
         result.coordSysMap[coordSysKey] = coordSys;
 
         // Set tooltip (like 'cross') is a convienent way to show axisPointer
         // for user. So we enable seting tooltip on coordSys model.
-        var coordSysModel = coordSys.model;
+        var coordSysModel = coordSys.model as ComponentModel<ComponentOption & {
+            tooltip: TooltipOption  // TODO: Same with top level tooltip?
+        }>;
         var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);
 
         each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null));
@@ -96,8 +150,8 @@ function collectAxesInfo(result, ecModel, api) {
             // Compatible with previous logic. But series.tooltip.trigger: 'axis'
             // or series.data[n].tooltip.trigger: 'axis' are not support any more.
             var triggerAxis = baseTooltipModel.get('trigger') === 'axis';
-            var cross = baseTooltipModel.get('axisPointer.type') === 'cross';
-            var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get('axisPointer.axis'));
+            var cross = baseTooltipModel.get(['axisPointer', 'type']) === 'cross';
+            var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get(['axisPointer', 'axis']));
             if (triggerAxis || cross) {
                 each(tooltipAxes.baseAxes, curry(
                     saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis
@@ -110,8 +164,14 @@ function collectAxesInfo(result, ecModel, api) {
 
         // fromTooltip: true | false | 'cross'
         // triggerTooltip: true | false | null
-        function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) {
-            var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel);
+        function saveTooltipAxisInfo(
+            fromTooltip: boolean | 'cross',
+            triggerTooltip: boolean,
+            axis: Axis
+        ) {
+            var axisPointerModel = axis.model.getModel(
+                'axisPointer', globalAxisPointerModel
+            ) as Model<CommonAxisPointerOption>;
 
             var axisPointerShow = axisPointerModel.get('show');
             if (!axisPointerShow || (
@@ -134,12 +194,12 @@ function collectAxesInfo(result, ecModel, api) {
                 : axisPointerModel;
 
             var snap = axisPointerModel.get('snap');
-            var key = makeKey(axis.model);
+            var axisKey = makeKey(axis.model);
             var involveSeries = triggerTooltip || snap || axis.type === 'category';
 
             // If result.axesInfo[key] exist, override it (tooltip has higher priority).
-            var axisInfo = result.axesInfo[key] = {
-                key: key,
+            var axisInfo: AxisInfo = result.axesInfo[axisKey] = {
+                key: axisKey,
                 axis: axis,
                 coordSys: coordSys,
                 axisPointerModel: axisPointerModel,
@@ -147,15 +207,18 @@ function collectAxesInfo(result, ecModel, api) {
                 involveSeries: involveSeries,
                 snap: snap,
                 useHandle: isHandleTrigger(axisPointerModel),
-                seriesModels: []
+                seriesModels: [],
+
+                linkGroup: null
             };
-            axesInfoInCoordSys[key] = axisInfo;
-            result.seriesInvolved |= involveSeries;
+            axesInfoInCoordSys[axisKey] = axisInfo;
+            result.seriesInvolved = result.seriesInvolved || involveSeries;
 
             var groupIndex = getLinkGroupIndex(linksOption, axis);
             if (groupIndex != null) {
-                var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = {axesInfo: {}});
-                linkGroup.axesInfo[key] = axisInfo;
+                var linkGroup: LinkGroup = linkGroups[groupIndex]
+                    || (linkGroups[groupIndex] = {axesInfo: {}} as LinkGroup);
+                linkGroup.axesInfo[axisKey] = axisInfo;
                 linkGroup.mapper = linksOption[groupIndex].mapper;
                 axisInfo.linkGroup = linkGroup;
             }
@@ -164,20 +227,23 @@ function collectAxesInfo(result, ecModel, api) {
 }
 
 function makeAxisPointerModel(
-    axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip
+    axis: Axis,
+    baseTooltipModel: Model<TooltipOption>,
+    globalAxisPointerModel: AxisPointerModel,
+    ecModel: GlobalModel,
+    fromTooltip: boolean | 'cross',
+    triggerTooltip: boolean
 ) {
-    var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
-    var volatileOption = {};
-
-    each(
-        [
-            'type', 'snap', 'lineStyle', 'shadowStyle', 'label',
-            'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'
-        ],
-        function (field) {
-            volatileOption[field] = zrUtil.clone(tooltipAxisPointerModel.get(field));
-        }
-    );
+    const tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
+    const fields = [
+        'type', 'snap', 'lineStyle', 'shadowStyle', 'label',
+        'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'
+    ] as const;
+    var volatileOption = {} as Pick<AxisPointerOption, typeof fields[number]>;
+
+    each(fields, function (field) {
+        (volatileOption as any)[field] = clone(tooltipAxisPointerModel.get(field));
+    });
 
     // category axis do not auto snap, otherwise some tick that do not
     // has value can not be hovered. value/time/log axis default snap if
@@ -195,13 +261,13 @@ function makeAxisPointerModel(
 
     if (fromTooltip === 'cross') {
         // When 'cross', both axes show labels.
-        var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get('label.show');
+        var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get(['label', 'show']);
         labelOption.show = tooltipAxisPointerLabelShow != null ? tooltipAxisPointerLabelShow : true;
         // If triggerTooltip, this is a base axis, which should better not use cross style
         // (cross style is dashed by default)
         if (!triggerTooltip) {
             var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle');
-            crossStyle && zrUtil.defaults(labelOption, crossStyle.textStyle);
+            crossStyle && defaults(labelOption, crossStyle.textStyle);
         }
     }
 
@@ -211,20 +277,23 @@ function makeAxisPointerModel(
     );
 }
 
-function collectSeriesInfo(result, ecModel) {
+function collectSeriesInfo(result: CollectionResult, ecModel: GlobalModel) {
     // Prepare data for axis trigger
-    ecModel.eachSeries(function (seriesModel) {
+    ecModel.eachSeries(function (seriesModel: SeriesModel<SeriesOption & {
+        tooltip?: SeriesTooltipOption
+        axisPointer?: CommonAxisPointerOption
+    }>) {
 
         // Notice this case: this coordSys is `cartesian2D` but not `grid`.
         var coordSys = seriesModel.coordinateSystem;
-        var seriesTooltipTrigger = seriesModel.get('tooltip.trigger', true);
-        var seriesTooltipShow = seriesModel.get('tooltip.show', true);
+        var seriesTooltipTrigger = seriesModel.get(['tooltip', 'trigger'], true);
+        var seriesTooltipShow = seriesModel.get(['tooltip', 'show'], true);
         if (!coordSys
             || seriesTooltipTrigger === 'none'
             || seriesTooltipTrigger === false
             || seriesTooltipTrigger === 'item'
             || seriesTooltipShow === false
-            || seriesModel.get('axisPointer.show', true) === false
+            || seriesModel.get(['axisPointer', 'show'], true) === false
         ) {
             return;
         }
@@ -238,7 +307,7 @@ function collectSeriesInfo(result, ecModel) {
             }
         });
 
-    }, this);
+    });
 }
 
 /**
@@ -255,27 +324,27 @@ function collectSeriesInfo(result, ecModel) {
  *     }
  * }
  */
-function getLinkGroupIndex(linksOption, axis) {
+function getLinkGroupIndex(linksOption: AxisPointerOption['link'], axis: Axis): number {
     var axisModel = axis.model;
     var dim = axis.dim;
     for (var i = 0; i < linksOption.length; i++) {
         var linkOption = linksOption[i] || {};
-        if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id)
-            || checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex)
-            || checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name)
+        if (checkPropInLink(linkOption[dim + 'AxisId' as 'xAxisId'], axisModel.id)
+            || checkPropInLink(linkOption[dim + 'AxisIndex' as 'xAxisIndex'], axisModel.componentIndex)
+            || checkPropInLink(linkOption[dim + 'AxisName' as 'xAxisName'], axisModel.name)
         ) {
             return i;
         }
     }
 }
 
-function checkPropInLink(linkPropValue, axisPropValue) {
+function checkPropInLink(linkPropValue: number[] | number | string | string[] | 'all', axisPropValue: number | string) {
     return linkPropValue === 'all'
-        || (zrUtil.isArray(linkPropValue) && zrUtil.indexOf(linkPropValue, axisPropValue) >= 0)
+        || (isArray(linkPropValue) && indexOf(linkPropValue, axisPropValue) >= 0)
         || linkPropValue === axisPropValue;
 }
 
-export function fixValue(axisModel) {
+export function fixValue(axisModel: AxisBaseModel) {
     var axisInfo = getAxisInfo(axisModel);
     if (!axisInfo) {
         return;
@@ -322,24 +391,25 @@ export function fixValue(axisModel) {
     }
 }
 
-export function getAxisInfo(axisModel) {
-    var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo;
+export function getAxisInfo(axisModel: AxisBaseModel) {
+    var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') as AxisPointerModel || {})
+        .coordSysAxesInfo as CollectionResult;
     return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)];
 }
 
-export function getAxisPointerModel(axisModel) {
+export function getAxisPointerModel(axisModel: AxisBaseModel) {
     var axisInfo = getAxisInfo(axisModel);
     return axisInfo && axisInfo.axisPointerModel;
 }
 
-function isHandleTrigger(axisPointerModel) {
-    return !!axisPointerModel.get('handle.show');
+function isHandleTrigger(axisPointerModel: Model<CommonAxisPointerOption>) {
+    return !!axisPointerModel.get(['handle', 'show']);
 }
 
 /**
  * @param {module:echarts/model/Model} model
  * @return {string} unique key
  */
-export function makeKey(model) {
+export function makeKey(model: ComponentModel) {
     return model.type + '||' + model.id;
 }
diff --git a/src/component/axisPointer/viewHelper.ts b/src/component/axisPointer/viewHelper.ts
index e2add8f..b26d2da 100644
--- a/src/component/axisPointer/viewHelper.ts
+++ b/src/component/axisPointer/viewHelper.ts
@@ -17,8 +17,6 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../../util/graphic';
 import * as textContain from 'zrender/src/contain/text';
@@ -26,14 +24,36 @@ import * as formatUtil from '../../util/format';
 import * as matrix from 'zrender/src/core/matrix';
 import * as axisHelper from '../../coord/axisHelper';
 import AxisBuilder from '../axis/AxisBuilder';
+import { StyleProps } from 'zrender/src/graphic/Style';
+import Axis from '../../coord/Axis';
+import {
+    ScaleDataValue, CallbackDataParams, ZRTextAlign, ZRTextVerticalAlign, ZRColor, CommonAxisPointerOption
+} from '../../util/types';
+import { VectorArray } from 'zrender/src/core/vector';
+import GlobalModel from '../../model/Global';
+import IntervalScale from '../../scale/Interval';
+import Axis2D from '../../coord/cartesian/Axis2D';
+import { AxisPointerElementOptions } from './BaseAxisPointer';
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
+import ExtensionAPI from '../../ExtensionAPI';
+import CartesianAxisModel from '../../coord/cartesian/AxisModel';
+import Model from '../../model/Model';
 
-/**
- * @param {module:echarts/model/Model} axisPointerModel
- */
-export function buildElStyle(axisPointerModel) {
+interface LayoutInfo {
+    position: VectorArray
+    rotation: number
+    labelOffset?: number
+    labelDirection?: -1 | 1
+    labelMargin?: number
+}
+
+// Not use top level axisPointer model
+type AxisPointerModel = Model<CommonAxisPointerOption>
+
+export function buildElStyle(axisPointerModel: AxisPointerModel) {
     var axisPointerType = axisPointerModel.get('type');
-    var styleModel = axisPointerModel.getModel(axisPointerType + 'Style');
-    var style;
+    var styleModel = axisPointerModel.getModel(axisPointerType + 'Style' as 'lineStyle' | 'shadowStyle');
+    var style: StyleProps;
     if (axisPointerType === 'line') {
         style = styleModel.getLineStyle();
         style.fill = null;
@@ -49,15 +69,23 @@ export function buildElStyle(axisPointerModel) {
  * @param {Function} labelPos {align, verticalAlign, position}
  */
 export function buildLabelElOption(
-    elOption, axisModel, axisPointerModel, api, labelPos
+    elOption: AxisPointerElementOptions,
+    axisModel: AxisBaseModel,
+    axisPointerModel: AxisPointerModel,
+    api: ExtensionAPI,
+    labelPos: {
+        align?: ZRTextAlign
+        verticalAlign?: ZRTextVerticalAlign
+        position: number[]
+    }
 ) {
     var value = axisPointerModel.get('value');
     var text = getValueLabel(
         value, axisModel.axis, axisModel.ecModel,
         axisPointerModel.get('seriesDataIndices'),
         {
-            precision: axisPointerModel.get('label.precision'),
-            formatter: axisPointerModel.get('label.formatter')
+            precision: axisPointerModel.get(['label', 'precision']),
+            formatter: axisPointerModel.get(['label', 'formatter'])
         }
     );
     var labelModel = axisPointerModel.getModel('label');
@@ -81,9 +109,9 @@ export function buildLabelElOption(
     // Not overflow ec container
     confineInContainer(position, width, height, api);
 
-    var bgColor = labelModel.get('backgroundColor');
+    var bgColor = labelModel.get('backgroundColor') as ZRColor;
     if (!bgColor || bgColor === 'auto') {
-        bgColor = axisModel.get('axisLine.lineStyle.color');
+        bgColor = axisModel.get(['axisLine', 'lineStyle', 'color']);
     }
 
     elOption.label = {
@@ -110,7 +138,7 @@ export function buildLabelElOption(
 }
 
 // Do not overflow ec container
-function confineInContainer(position, width, height, api) {
+function confineInContainer(position: number[], width: number, height: number, api: ExtensionAPI) {
     var viewWidth = api.getWidth();
     var viewHeight = api.getHeight();
     position[0] = Math.min(position[0] + width, viewWidth) - width;
@@ -119,21 +147,23 @@ function confineInContainer(position, width, height, api) {
     position[1] = Math.max(position[1], 0);
 }
 
-/**
- * @param {number} value
- * @param {module:echarts/coord/Axis} axis
- * @param {module:echarts/model/Global} ecModel
- * @param {Object} opt
- * @param {Array.<Object>} seriesDataIndices
- * @param {number|string} opt.precision 'auto' or a number
- * @param {string|Function} opt.formatter label formatter
- */
-export function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
+export function getValueLabel(
+    value: ScaleDataValue,
+    axis: Axis,
+    ecModel: GlobalModel,
+    seriesDataIndices: CommonAxisPointerOption['seriesDataIndices'],
+    opt?: {
+        precision?: number | 'auto'
+        formatter?: CommonAxisPointerOption['label']['formatter']
+    }
+): string {
     value = axis.scale.parse(value);
-    var text = axis.scale.getLabel(
+    var text = (axis.scale as IntervalScale).getLabel(
         // If `precision` is set, width can be fixed (like '12.00500'), which
         // helps to debounce when when moving label.
-        value, {precision: opt.precision}
+        value, {
+            precision: opt.precision
+        }
     );
     var formatter = opt.formatter;
 
@@ -141,8 +171,8 @@ export function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
         var params = {
             value: axisHelper.getAxisRawValue(axis, value),
             axisDimension: axis.dim,
-            axisIndex: axis.index,
-            seriesData: []
+            axisIndex: (axis as Axis2D).index,  // Only Carteian Axis has index
+            seriesData: [] as CallbackDataParams[]
         };
         zrUtil.each(seriesDataIndices, function (idxItem) {
             var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
@@ -162,14 +192,11 @@ export function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
     return text;
 }
 
-/**
- * @param {module:echarts/coord/Axis} axis
- * @param {number} value
- * @param {Object} layoutInfo {
- *  rotation, position, labelOffset, labelDirection, labelMargin
- * }
- */
-export function getTransformedPosition(axis, value, layoutInfo) {
+export function getTransformedPosition(
+    axis: Axis,
+    value: ScaleDataValue,
+    layoutInfo: LayoutInfo
+): number[] {
     var transform = matrix.create();
     matrix.rotate(transform, transform, layoutInfo.rotation);
     matrix.translate(transform, transform, layoutInfo.position);
@@ -182,12 +209,18 @@ export function getTransformedPosition(axis, value, layoutInfo) {
 }
 
 export function buildCartesianSingleLabelElOption(
-    value, elOption, layoutInfo, axisModel, axisPointerModel, api
+    value: ScaleDataValue,
+    elOption: AxisPointerElementOptions,
+    layoutInfo: LayoutInfo,
+    axisModel: CartesianAxisModel,
+    axisPointerModel: AxisPointerModel,
+    api: ExtensionAPI
 ) {
+    // @ts-ignore
     var textLayout = AxisBuilder.innerTextLayout(
         layoutInfo.rotation, 0, layoutInfo.labelDirection
     );
-    layoutInfo.labelMargin = axisPointerModel.get('label.margin');
+    layoutInfo.labelMargin = axisPointerModel.get(['label', 'margin']);
     buildLabelElOption(elOption, axisModel, axisPointerModel, api, {
         position: getTransformedPosition(axisModel.axis, value, layoutInfo),
         align: textLayout.textAlign,
@@ -195,12 +228,7 @@ export function buildCartesianSingleLabelElOption(
     });
 }
 
-/**
- * @param {Array.<number>} p1
- * @param {Array.<number>} p2
- * @param {number} [xDimIndex=0] or 1
- */
-export function makeLineShape(p1, p2, xDimIndex) {
+export function makeLineShape(p1: number[], p2: number[], xDimIndex?: number) {
     xDimIndex = xDimIndex || 0;
     return {
         x1: p1[xDimIndex],
@@ -210,12 +238,7 @@ export function makeLineShape(p1, p2, xDimIndex) {
     };
 }
 
-/**
- * @param {Array.<number>} xy
- * @param {Array.<number>} wh
- * @param {number} [xDimIndex=0] or 1
- */
-export function makeRectShape(xy, wh, xDimIndex) {
+export function makeRectShape(xy: number[], wh: number[], xDimIndex?: number) {
     xDimIndex = xDimIndex || 0;
     return {
         x: xy[xDimIndex],
@@ -225,7 +248,14 @@ export function makeRectShape(xy, wh, xDimIndex) {
     };
 }
 
-export function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) {
+export function makeSectorShape(
+    cx: number,
+    cy: number,
+    r0: number,
+    r: number,
+    startAngle: number,
+    endAngle: number
+) {
     return {
         cx: cx,
         cy: cy,
diff --git a/src/component/tooltip/TooltipView.ts b/src/component/tooltip/TooltipView.ts
index 5b746ed..60dfc20 100644
--- a/src/component/tooltip/TooltipView.ts
+++ b/src/component/tooltip/TooltipView.ts
@@ -47,8 +47,7 @@ import ExtensionAPI from '../../ExtensionAPI';
 import TooltipModel, {TooltipOption} from './TooltipModel';
 import Element from 'zrender/src/Element';
 import { Dictionary } from 'zrender/src/core/types';
-import Axis from '../../coord/Axis';
-import ComponentModel from '../../model/Component';
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
 
 const bind = zrUtil.bind;
 const each = zrUtil.each;
@@ -58,10 +57,6 @@ const proxyRect = new graphic.Rect({
     shape: {x: -1, y: -1, width: 2, height: 2}
 });
 
-type AxisModel = ComponentModel & {
-    axis: Axis
-}
-
 interface DataIndex {
     seriesIndex: number
     dataIndex: number
@@ -514,7 +509,7 @@ class TooltipView extends ComponentView {
             // var paramsList = displayMode === 'single' ? singleParamsList : [];
 
             each(itemCoordSys.dataByAxis, function (item) {
-                var axisModel = ecModel.getComponent(item.axisDim + 'Axis', item.axisIndex);
+                var axisModel = ecModel.getComponent(item.axisDim + 'Axis', item.axisIndex) as AxisBaseModel;
                 var axisValue = item.value;
                 var seriesDefaultHTML: string[] = [];
 
@@ -523,7 +518,7 @@ class TooltipView extends ComponentView {
                 }
 
                 var valueLabel = axisPointerViewHelper.getValueLabel(
-                    axisValue, (axisModel as AxisModel).axis, ecModel,
+                    axisValue, axisModel.axis, ecModel,
                     item.seriesDataIndices,
                     // @ts-ignore
                     item.valueLabelOpt
@@ -537,7 +532,7 @@ class TooltipView extends ComponentView {
                     dataParams.axisIndex = item.axisIndex;
                     dataParams.axisType = item.axisType;
                     dataParams.axisId = item.axisId;
-                    dataParams.axisValue = axisHelper.getAxisRawValue((axisModel as AxisModel).axis, axisValue);
+                    dataParams.axisValue = axisHelper.getAxisRawValue(axisModel.axis, axisValue);
                     dataParams.axisValueLabel = valueLabel;
 
                     if (dataParams) {
diff --git a/src/coord/Axis.ts b/src/coord/Axis.ts
index 90a0f1c..199189b 100644
--- a/src/coord/Axis.ts
+++ b/src/coord/Axis.ts
@@ -29,6 +29,7 @@ import { DimensionName, ScaleDataValue } from '../util/types';
 import OrdinalScale from '../scale/Ordinal';
 import Model from '../model/Model';
 import { AxisBaseOption, OptionAxisType } from './axisCommonTypes';
+import { AxisBaseModel } from './AxisBaseModel';
 
 var NORMALIZED_EXTENT = [0, 1] as [number, number];
 
@@ -37,7 +38,6 @@ interface TickCoord {
     tickValue?: number;
 }
 
-
 /**
  * Base class of Axis.
  */
@@ -61,7 +61,7 @@ class Axis {
     private _extent: [number, number];
 
     // Injected outside
-    model: Model;
+    model: AxisBaseModel;
     onBand: AxisBaseOption['boundaryGap'] = false;
     inverse: AxisBaseOption['inverse'] = false;
 
diff --git a/src/coord/CoordinateSystem.ts b/src/coord/CoordinateSystem.ts
index 1dead51..86763d9 100644
--- a/src/coord/CoordinateSystem.ts
+++ b/src/coord/CoordinateSystem.ts
@@ -17,7 +17,6 @@
 * under the License.
 */
 
-import Model from '../model/Model';
 import GlobalModel from '../model/Global';
 import {ParsedModelFinder} from '../util/model';
 import ExtensionAPI from '../ExtensionAPI';
@@ -52,7 +51,7 @@ export interface CoordinateSystemMaster {
     // Should be the same as its coordinateSystemCreator.
     dimensions: DimensionName[];
 
-    model?: Model;
+    model?: ComponentModel;
 
     update?: (ecModel: GlobalModel, api: ExtensionAPI) => void;
 
@@ -101,7 +100,7 @@ export interface CoordinateSystem {
     // Should be the same as its coordinateSystemCreator.
     dimensions: DimensionName[];
 
-    model?: Model;
+    model?: ComponentModel;
 
     // @param data
     // @param reserved Defined by the coordinate system itself
diff --git a/src/coord/axisModelCommonMixin.ts b/src/coord/axisModelCommonMixin.ts
index d041f52..3657667 100644
--- a/src/coord/axisModelCommonMixin.ts
+++ b/src/coord/axisModelCommonMixin.ts
@@ -20,7 +20,6 @@
 import * as zrUtil from 'zrender/src/core/util';
 import Model from '../model/Model';
 import Axis from './Axis';
-import ComponentModel from '../model/Component';
 import { AxisBaseOption } from './axisCommonTypes';
 import { CoordinateSystemHostModel } from './CoordinateSystem';
 
diff --git a/src/coord/polar/AxisModel.ts b/src/coord/polar/AxisModel.ts
index 1d41b92..d5714ee 100644
--- a/src/coord/polar/AxisModel.ts
+++ b/src/coord/polar/AxisModel.ts
@@ -63,6 +63,8 @@ class PolarAxisModel<T extends PolarAxisOption = PolarAxisOption> extends Compon
     implements AxisBaseModel<T> {
     static type = 'polarAxis'
 
+    axis: AngleAxis | RadiusAxis
+
     getCoordSysModel(): ComponentModel {
         return this.ecModel.queryComponents({
             mainType: 'polar',
diff --git a/src/coord/polar/prepareCustom.ts b/src/coord/polar/prepareCustom.ts
index 01c2a4d..b622da2 100644
--- a/src/coord/polar/prepareCustom.ts
+++ b/src/coord/polar/prepareCustom.ts
@@ -30,11 +30,10 @@ function dataToCoordSize(this: Polar, dataSize: number[], dataItem: number[]) {
         const axis = this[getterName]() as RadiusAxis;
         const val = dataItem[dimIdx];
         const halfSize = dataSize[dimIdx] / 2;
-        const converterName = 'dataTo' + dim as 'dataToRadius';
 
         var result = axis.type === 'category'
             ? axis.getBandWidth()
-            : Math.abs(axis[converterName](val - halfSize) - axis[converterName](val + halfSize));
+            : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize));
 
         if (dim === 'Angle') {
             result = result * Math.PI / 180;
diff --git a/src/coord/single/Single.ts b/src/coord/single/Single.ts
index 26313b6..b6a34cd 100644
--- a/src/coord/single/Single.ts
+++ b/src/coord/single/Single.ts
@@ -249,7 +249,7 @@ class Single implements CoordinateSystem, CoordinateSystemMaster {
     }
 }
 
-function getCoordSys(finder: ParsedModelFinder) {
+function getCoordSys(finder: ParsedModelFinder): Single {
     const seriesModel = finder.seriesModel;
     const polarModel = finder.singleAxisModel as SingleAxisModel;
     return polarModel && polarModel.coordinateSystem
diff --git a/src/model/Model.ts b/src/model/Model.ts
index e814590..6cf80f3 100644
--- a/src/model/Model.ts
+++ b/src/model/Model.ts
@@ -17,10 +17,6 @@
 * under the License.
 */
 
-/**
- * @module echarts/model/Model
- */
-
 import * as zrUtil from 'zrender/src/core/util';
 import env from 'zrender/src/core/env';
 import {makeInner} from '../util/model';
diff --git a/src/model/Series.ts b/src/model/Series.ts
index 3c20b0f..4f91679 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -53,19 +53,13 @@ import { PipelineContext, SeriesTaskContext, GeneralTask, OverallTask, SeriesTas
 import LegendVisualProvider from '../visual/LegendVisualProvider';
 import List from '../data/List';
 import Source from '../data/Source';
+import Axis from '../coord/Axis';
 
 var inner = modelUtil.makeInner<{
     data: List
     dataBeforeProcessed: List
 }>();
 
-// methods that can be implemented optionally to provide to components
-interface SeriesModel {
-    /**
-     * Get dimension to render shadow in dataZoom component
-     */
-    getShadowDim?(): string
-}
 class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentModel<Opt> {
 
     // [Caution]: for compat the previous "class extend"
@@ -529,8 +523,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
     getAxisTooltipData: (
         dim: DimensionName[],
         value: AxisValue,
-        // @ts-ignore
-        baseAxis // FIXME:TS baseAxis type should be coord Axis
+        baseAxis: Axis
     ) => {
         dataIndices: number[],
         nestestValue: any
@@ -560,7 +553,14 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
 }
 
 interface SeriesModel<Opt extends SeriesOption = SeriesOption>
-    extends DataFormatMixin, ColorPaletteMixin<Opt>, DataHost {}
+    extends DataFormatMixin, ColorPaletteMixin<Opt>, DataHost {
+
+    // methods that can be implemented optionally to provide to components
+    /**
+     * Get dimension to render shadow in dataZoom component
+     */
+    getShadowDim?(): string
+}
 zrUtil.mixin(SeriesModel, DataFormatMixin);
 zrUtil.mixin(SeriesModel, ColorPaletteMixin);
 
diff --git a/src/model/mixin/areaStyle.ts b/src/model/mixin/areaStyle.ts
index ca404c8..b3d097e 100644
--- a/src/model/mixin/areaStyle.ts
+++ b/src/model/mixin/areaStyle.ts
@@ -43,8 +43,8 @@ type AreaStyleProps = Pick<StyleProps,
 class AreaStyleMixin {
     getAreaStyle(
         this: Model,
-        excludes?: (keyof AreaStyleOption)[],
-        includes?: (keyof AreaStyleOption)[]
+        excludes?: readonly (keyof AreaStyleOption)[],
+        includes?: readonly (keyof AreaStyleOption)[]
     ): AreaStyleProps {
         return getAreaStyle(this, excludes, includes);
     }
diff --git a/src/model/mixin/itemStyle.ts b/src/model/mixin/itemStyle.ts
index 5eb57ca..7dd3027 100644
--- a/src/model/mixin/itemStyle.ts
+++ b/src/model/mixin/itemStyle.ts
@@ -51,7 +51,11 @@ type ItemStyleProps = Pick<StyleProps, ItemStyleKeys>
 
 class ItemStyleMixin {
 
-    getItemStyle(this: Model, excludes?: (keyof ItemStyleOption)[], includes?: (keyof ItemStyleOption)[]): ItemStyleProps {
+    getItemStyle(
+        this: Model,
+        excludes?: readonly (keyof ItemStyleOption)[],
+        includes?: readonly (keyof ItemStyleOption)[]
+    ): ItemStyleProps {
         var style = getItemStyle(this, excludes, includes);
         var lineDash = this.getBorderLineDash();
         lineDash && ((style as any).lineDash = lineDash);
diff --git a/src/model/mixin/lineStyle.ts b/src/model/mixin/lineStyle.ts
index c28e75b..073f6ed 100644
--- a/src/model/mixin/lineStyle.ts
+++ b/src/model/mixin/lineStyle.ts
@@ -44,7 +44,7 @@ type LineStyleProps = Pick<StyleProps, LineStyleKeys>
 
 class LineStyleMixin {
 
-    getLineStyle(this: Model, excludes?: (keyof LineStyleOption)[]): LineStyleProps {
+    getLineStyle(this: Model, excludes?: readonly (keyof LineStyleOption)[]): LineStyleProps {
         var style = getLineStyle(this, excludes);
         // Always set lineDash whether dashed, otherwise we can not
         // erase the previous style when assigning to el.style.
diff --git a/src/model/mixin/makeStyleMapper.ts b/src/model/mixin/makeStyleMapper.ts
index ff1b2e3..48ac9c5 100644
--- a/src/model/mixin/makeStyleMapper.ts
+++ b/src/model/mixin/makeStyleMapper.ts
@@ -30,7 +30,7 @@ export default function (properties: readonly string[][]) {
             properties[i][1] = properties[i][0];
         }
     }
-    return function (model: Model, excludes: string[], includes?: string[]) {
+    return function (model: Model, excludes: readonly string[], includes?: readonly string[]) {
         var style: Dictionary<any> = {};
         for (var i = 0; i < properties.length; i++) {
             var propName = properties[i][1];
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 5ea19bd..9a6fba1 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -1293,7 +1293,7 @@ export function applyTransform(
     target: vector.VectorArray,
     transform: Transformable | matrix.MatrixArray,
     invert?: boolean
-): vector.VectorArray {
+): number[] {
     if (transform && !zrUtil.isArrayLike(transform)) {
         transform = Transformable.getLocalTransform(transform);
     }
diff --git a/src/util/model.ts b/src/util/model.ts
index 482310d..25e65c9 100644
--- a/src/util/model.ts
+++ b/src/util/model.ts
@@ -34,14 +34,14 @@ import GlobalModel, { QueryConditionKindB } from '../model/Global';
 import ComponentModel from '../model/Component';
 import List from '../data/List';
 import {
-    Payload,
     ComponentOption,
     ComponentMainType,
     ComponentSubType,
     DisplayStateHostOption,
     OptionDataItem,
     OptionDataValue,
-    TooltipRenderMode
+    TooltipRenderMode,
+    Payload
 } from './types';
 import { Dictionary } from 'zrender/src/core/types';
 import SeriesModel from '../model/Series';
@@ -422,7 +422,11 @@ export function compressBatches(
  *                         each of which can be Array or primary type.
  * @return dataIndex If not found, return undefined/null.
  */
-export function queryDataIndex(data: List, payload: Payload): number | number[] {
+export function queryDataIndex(data: List, payload: Payload & {
+    dataIndexInside?: number | number[]
+    dataIndex?: number | number[]
+    name?: string | string[]
+}): number | number[] {
     if (payload.dataIndexInside != null) {
         return payload.dataIndexInside;
     }
diff --git a/src/util/types.ts b/src/util/types.ts
index ee5717e..2d954b7 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -793,6 +793,7 @@ interface PositionCallback {
 }
 /**
  * Common tooltip option
+ * Can be configured on series, graphic elements
  */
 export interface CommonTooltipOption<FormatterParams> {
 
@@ -871,10 +872,106 @@ export interface CommonTooltipOption<FormatterParams> {
 /**
  * Tooltip option configured on each series
  */
-export type SeriesTooltipOption = CommonTooltipOption<CallbackDataParams>
+export type SeriesTooltipOption = CommonTooltipOption<CallbackDataParams> & {
+    trigger?: 'item' | 'axis' | boolean | 'none'
+}
+
+type LabelFormatterParams = {
+    value: ScaleDataValue
+    axisDimension: string
+    axisIndex: number
+    seriesData: CallbackDataParams[]
+}
+/**
+ * Common axis option. can be configured on each axis
+ */
+export interface CommonAxisPointerOption {
+    show?: boolean | 'auto'
+
+    z?: number;
+    zlevel?: number;
+
+    triggerOn?: 'click' | 'mousemove' | 'none' | 'mousemove|click'
+
+    type?: 'line' | 'shadow' | 'none'
+
+    snap?: boolean
+
+    triggerTooltip?: boolean
+
+    /**
+     * current value. When using axisPointer.handle, value can be set to define the initail position of axisPointer.
+     */
+    // TODO: TYPE Only support numeric value?
+    value?: ParsedValueNumeric
+
+    status?: 'show' | 'hide'
+
+    // [group0, group1, ...]
+    // Each group can be: {
+    //      mapper: function () {},
+    //      singleTooltip: 'multiple',  // 'multiple' or 'single'
+    //      xAxisId: ...,
+    //      yAxisName: ...,
+    //      angleAxisIndex: ...
+    // }
+    // mapper: can be ignored.
+    //      input: {axisInfo, value}
+    //      output: {axisInfo, value}
+
+    label?: LabelOption & {
+        precision?: 'auto' | number
+        margin?: number
+        /**
+         * String template include variable {value} or callback function
+         */
+        formatter?: string | ((params: LabelFormatterParams) => string)
+    }
+    animation?: boolean | 'auto'
+    animationDurationUpdate?: number
+    animationEasingUpdate?: ZREasing
+
+    /**
+     * Available when type is 'line'
+     */
+    lineStyle?: LineStyleOption
+    /**
+     * Available when type is 'shadow'
+     */
+    shadowStyle?: AreaStyleOption
+
+    handle?: {
+        show?: boolean
+        icon?: string
+        /**
+         * The size of the handle
+         */
+        size?: number | number[]
+        /**
+         * Distance from handle center to axis.
+         */
+        margin?: number
+
+        color?: ColorString
+
+        /**
+         * Throttle for mobile performance
+         */
+        throttle?: number
+    } & ShadowOptionMixin
+
+
+    seriesDataIndices?: {
+        seriesIndex: number
+        dataIndex: number
+        dataIndexInside: number
+    }[]
+
+}
 
 export interface ComponentOption {
     type?: string;
+
     id?: string;
     name?: string;
 
diff --git a/src/visual/symbol.ts b/src/visual/symbol.ts
index cd0bb05..facc227 100644
--- a/src/visual/symbol.ts
+++ b/src/visual/symbol.ts
@@ -23,7 +23,7 @@ import List from '../data/List';
 import SeriesModel from '../model/Series';
 import GlobalModel from '../model/Global';
 
-export default function (seriesType: string, defaultSymbolType: string, legendSymbol: string): StageHandler {
+export default function (seriesType: string, defaultSymbolType: string, legendSymbol?: string): StageHandler {
     // Encoding visual for all series include which is filtered for legend drawing
     return {
         seriesType: seriesType,


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org