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/03/13 12:44:29 UTC

[incubator-echarts] branch typescript updated: ts: add types for axis and grid. direction use number instead of 1 | -1

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 15a464e  ts: add types for axis and grid. direction use number instead of 1 | -1
15a464e is described below

commit 15a464e27c4696dba52b842078617fd7db54c55e
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Mar 13 20:43:55 2020 +0800

    ts: add types for axis and grid. direction use number instead of 1 | -1
---
 src/component/axis/AngleAxisView.ts           | 156 ++++----
 src/component/axis/AxisBuilder.ts             | 522 ++++++++++++++------------
 src/component/axis/AxisView.ts                | 114 +++---
 src/component/axis/CartesianAxisView.ts       |  98 ++---
 src/component/axis/RadiusAxisView.ts          |  93 +++--
 src/component/axis/SingleAxisView.ts          |  52 ++-
 src/component/axis/axisSplitHelper.ts         |  36 +-
 src/component/axisPointer/PolarAxisPointer.ts |  11 +-
 src/component/axisPointer/viewHelper.ts       |   5 +-
 src/component/gridSimple.ts                   |  21 +-
 src/coord/axisCommonTypes.ts                  |  14 +-
 src/coord/single/singleAxisHelper.ts          |  10 +-
 src/model/Component.ts                        |   8 +-
 src/model/mixin/textStyle.ts                  |   1 +
 14 files changed, 649 insertions(+), 492 deletions(-)

diff --git a/src/component/axis/AngleAxisView.ts b/src/component/axis/AngleAxisView.ts
index d2a483a..79eba2e 100644
--- a/src/component/axis/AngleAxisView.ts
+++ b/src/component/axis/AngleAxisView.ts
@@ -17,17 +17,29 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../../util/graphic';
 import Model from '../../model/Model';
 import AxisView from './AxisView';
 import AxisBuilder from './AxisBuilder';
-
-var elementList = ['axisLine', 'axisLabel', 'axisTick', 'minorTick', 'splitLine', 'minorSplitLine', 'splitArea'];
-
-function getAxisLineShape(polar, rExtent, angle) {
+import { AngleAxisModel } from '../../coord/polar/AxisModel';
+import GlobalModel from '../../model/Global';
+import Polar from '../../coord/polar/Polar';
+import ComponentView from '../../view/Component';
+import AngleAxis from '../../coord/polar/AngleAxis';
+import { ZRTextAlign, ZRTextVerticalAlign } from '../../util/types';
+
+var elementList = [
+    'axisLine',
+    'axisLabel',
+    'axisTick',
+    'minorTick',
+    'splitLine',
+    'minorSplitLine',
+    'splitArea'
+] as const;
+
+function getAxisLineShape(polar: Polar, rExtent: number[], angle: number) {
     rExtent[1] > rExtent[0] && (rExtent = rExtent.slice().reverse());
     var start = polar.coordToPoint([rExtent[0], angle]);
     var end = polar.coordToPoint([rExtent[1], angle]);
@@ -40,13 +52,13 @@ function getAxisLineShape(polar, rExtent, angle) {
     };
 }
 
-function getRadiusIdx(polar) {
+function getRadiusIdx(polar: Polar) {
     var radiusAxis = polar.getRadiusAxis();
     return radiusAxis.inverse ? 0 : 1;
 }
 
 // Remove the last tick which will overlap the first tick
-function fixAngleOverlap(list) {
+function fixAngleOverlap(list: TickCoord[]) {
     var firstItem = list[0];
     var lastItem = list[list.length - 1];
     if (firstItem
@@ -57,13 +69,19 @@ function fixAngleOverlap(list) {
     }
 }
 
-export default AxisView.extend({
+type TickCoord = ReturnType<AngleAxis['getTicksCoords']>[number];
+type TickLabel = ReturnType<AngleAxis['getViewLabels']>[number] & {
+    coord: number
+}
+
+class AngleAxisView extends AxisView {
 
-    type: 'angleAxis',
+    static readonly type = 'angleAxis'
+    readonly type = AngleAxisView.type
 
-    axisPointerClass: 'PolarAxisPointer',
+    axisPointerClass = 'PolarAxisPointer'
 
-    render: function (angleAxisModel, ecModel) {
+    render(angleAxisModel: AngleAxisModel, ecModel: GlobalModel) {
         this.group.removeAll();
         if (!angleAxisModel.get('show')) {
             return;
@@ -76,7 +94,7 @@ export default AxisView.extend({
         var ticksAngles = angleAxis.getTicksCoords();
         var minorTickAngles = angleAxis.getMinorTicksCoords();
 
-        var labels = zrUtil.map(angleAxis.getViewLabels(), function (labelItem) {
+        var labels = zrUtil.map(angleAxis.getViewLabels(), function (labelItem: TickLabel) {
             var labelItem = zrUtil.clone(labelItem);
             labelItem.coord = angleAxis.dataToCoord(labelItem.tickValue);
             return labelItem;
@@ -86,19 +104,34 @@ export default AxisView.extend({
         fixAngleOverlap(ticksAngles);
 
         zrUtil.each(elementList, function (name) {
-            if (angleAxisModel.get(name + '.show')
+            if (angleAxisModel.get([name, 'show'])
                 && (!angleAxis.scale.isBlank() || name === 'axisLine')
             ) {
-                this['_' + name](angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels);
+                angelAxisElementsBuilders[name](
+                    this.group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels
+                );
             }
         }, this);
-    },
+    }
 
-    /**
-     * @private
-     */
-    _axisLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
-        var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle');
+}
+
+interface AngleAxisElementBuilder {
+    (
+        group: graphic.Group,
+        angleAxisModel: AngleAxisModel,
+        polar: Polar,
+        ticksAngles: TickCoord[],
+        minorTickAngles: TickCoord[][],
+        radiusExtent: number[],
+        labels?: TickLabel[]
+    ): void
+}
+
+const angelAxisElementsBuilders: Record<typeof elementList[number], AngleAxisElementBuilder> = {
+
+    axisLine(group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
+        var lineStyleModel = angleAxisModel.getModel(['axisLine', 'lineStyle']);
 
         // extent id of the axis radius (r0 and r)
         var rId = getRadiusIdx(polar);
@@ -131,13 +164,10 @@ export default AxisView.extend({
             });
         }
         shape.style.fill = null;
-        this.group.add(shape);
+        group.add(shape);
     },
 
-    /**
-     * @private
-     */
-    _axisTick: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
+    axisTick(group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
         var tickModel = angleAxisModel.getModel('axisTick');
 
         var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');
@@ -148,22 +178,19 @@ export default AxisView.extend({
                 shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngleItem.coord)
             });
         });
-        this.group.add(graphic.mergePath(
+        group.add(graphic.mergePath(
             lines, {
                 style: zrUtil.defaults(
                     tickModel.getModel('lineStyle').getLineStyle(),
                     {
-                        stroke: angleAxisModel.get('axisLine.lineStyle.color')
+                        stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color'])
                     }
                 )
             }
         ));
     },
 
-    /**
-     * @private
-     */
-    _minorTick: function (angleAxisModel, polar, tickAngles, minorTickAngles, radiusExtent) {
+    minorTick(group, angleAxisModel, polar, tickAngles, minorTickAngles, radiusExtent) {
         if (!minorTickAngles.length) {
             return;
         }
@@ -184,13 +211,13 @@ export default AxisView.extend({
             }
         }
 
-        this.group.add(graphic.mergePath(
+        group.add(graphic.mergePath(
             lines, {
                 style: zrUtil.defaults(
                     minorTickModel.getModel('lineStyle').getLineStyle(),
                     zrUtil.defaults(
                         tickModel.getLineStyle(), {
-                            stroke: angleAxisModel.get('axisLine.lineStyle.color')
+                            stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color'])
                         }
                     )
                 )
@@ -198,10 +225,7 @@ export default AxisView.extend({
         ));
     },
 
-    /**
-     * @private
-     */
-    _axisLabel: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels) {
+    axisLabel(group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels) {
         var rawCategoryData = angleAxisModel.getCategories(true);
 
         var commonLabelModel = angleAxisModel.getModel('axisLabel');
@@ -219,25 +243,28 @@ export default AxisView.extend({
             var cx = polar.cx;
             var cy = polar.cy;
 
-            var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3
+            var labelTextAlign: ZRTextAlign = Math.abs(p[0] - cx) / r < 0.3
                 ? 'center' : (p[0] > cx ? 'left' : 'right');
-            var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3
+            var labelTextVerticalAlign: ZRTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3
                 ? 'middle' : (p[1] > cy ? 'top' : 'bottom');
 
-            if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) {
-                labelModel = new Model(
-                    rawCategoryData[tickValue].textStyle, commonLabelModel, commonLabelModel.ecModel
-                );
+            if (rawCategoryData && rawCategoryData[tickValue]) {
+                const rawCategoryItem = rawCategoryData[tickValue];
+                if (zrUtil.isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
+                    labelModel = new Model(
+                        rawCategoryItem.textStyle, commonLabelModel, commonLabelModel.ecModel
+                    );
+                    }
             }
 
             var textEl = new graphic.Text({
                 silent: AxisBuilder.isLabelSilent(angleAxisModel)
             });
-            this.group.add(textEl);
+            group.add(textEl);
             graphic.setTextStyle(textEl.style, labelModel, {
                 x: p[0],
                 y: p[1],
-                textFill: labelModel.getTextColor() || angleAxisModel.get('axisLine.lineStyle.color'),
+                textFill: labelModel.getTextColor() || angleAxisModel.get(['axisLine', 'lineStyle', 'color']),
                 text: labelItem.formattedLabel,
                 textAlign: labelTextAlign,
                 textVerticalAlign: labelTextVerticalAlign
@@ -245,18 +272,16 @@ export default AxisView.extend({
 
             // Pack data for mouse event
             if (triggerEvent) {
-                textEl.eventData = AxisBuilder.makeAxisEventDataBase(angleAxisModel);
-                textEl.eventData.targetType = 'axisLabel';
-                textEl.eventData.value = labelItem.rawLabel;
+                const eventData = AxisBuilder.makeAxisEventDataBase(angleAxisModel);
+                eventData.targetType = 'axisLabel';
+                eventData.value = labelItem.rawLabel;
+                graphic.getECData(textEl).eventData = eventData;
             }
 
         }, this);
     },
 
-    /**
-     * @private
-     */
-    _splitLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
+    splitLine(group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
         var splitLineModel = angleAxisModel.getModel('splitLine');
         var lineStyleModel = splitLineModel.getModel('lineStyle');
         var lineColors = lineStyleModel.get('color');
@@ -264,7 +289,7 @@ export default AxisView.extend({
 
         lineColors = lineColors instanceof Array ? lineColors : [lineColors];
 
-        var splitLines = [];
+        var splitLines: graphic.Line[][] = [];
 
         for (var i = 0; i < ticksAngles.length; i++) {
             var colorIndex = (lineCount++) % lineColors.length;
@@ -277,7 +302,7 @@ export default AxisView.extend({
         // Simple optimization
         // Batching the lines if color are the same
         for (var i = 0; i < splitLines.length; i++) {
-            this.group.add(graphic.mergePath(splitLines[i], {
+            group.add(graphic.mergePath(splitLines[i], {
                 style: zrUtil.defaults({
                     stroke: lineColors[i % lineColors.length]
                 }, lineStyleModel.getLineStyle()),
@@ -287,10 +312,7 @@ export default AxisView.extend({
         }
     },
 
-    /**
-     * @private
-     */
-    _minorSplitLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
+    minorSplitLine(group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
         if (!minorTickAngles.length) {
             return;
         }
@@ -308,17 +330,14 @@ export default AxisView.extend({
             }
         }
 
-        this.group.add(graphic.mergePath(lines, {
+        group.add(graphic.mergePath(lines, {
             style: lineStyleModel.getLineStyle(),
             silent: true,
             z: angleAxisModel.get('z')
         }));
     },
 
-    /**
-     * @private
-     */
-    _splitArea: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
+    splitArea(group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
         if (!ticksAngles.length) {
             return;
         }
@@ -330,7 +349,7 @@ export default AxisView.extend({
 
         areaColors = areaColors instanceof Array ? areaColors : [areaColors];
 
-        var splitAreas = [];
+        var splitAreas: graphic.Sector[][] = [];
 
         var RADIAN = Math.PI / 180;
         var prevAngle = -ticksAngles[0].coord * RADIAN;
@@ -360,7 +379,7 @@ export default AxisView.extend({
         // Simple optimization
         // Batching the lines if color are the same
         for (var i = 0; i < splitAreas.length; i++) {
-            this.group.add(graphic.mergePath(splitAreas[i], {
+            group.add(graphic.mergePath(splitAreas[i], {
                 style: zrUtil.defaults({
                     fill: areaColors[i % areaColors.length]
                 }, areaStyleModel.getAreaStyle()),
@@ -368,4 +387,7 @@ export default AxisView.extend({
             }));
         }
     }
-});
\ No newline at end of file
+};
+
+
+ComponentView.registerClass(AngleAxisView);
diff --git a/src/component/axis/AxisBuilder.ts b/src/component/axis/AxisBuilder.ts
index 66acaa8..b99f8a9 100644
--- a/src/component/axis/AxisBuilder.ts
+++ b/src/component/axis/AxisBuilder.ts
@@ -17,9 +17,7 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import {retrieve, defaults, extend, each} from 'zrender/src/core/util';
+import {retrieve, defaults, extend, each, isObject} from 'zrender/src/core/util';
 import * as formatUtil from '../../util/format';
 import * as graphic from '../../util/graphic';
 import Model from '../../model/Model';
@@ -28,10 +26,82 @@ import {createSymbol} from '../../util/symbol';
 import * as matrixUtil from 'zrender/src/core/matrix';
 import {applyTransform as v2ApplyTransform} from 'zrender/src/core/vector';
 import {shouldShowAllLabels} from '../../coord/axisHelper';
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
+import { ZRTextVerticalAlign, ZRTextAlign, ECElement } from '../../util/types';
+import { AxisBaseOption } from '../../coord/axisCommonTypes';
+import { StyleProps } from 'zrender/src/graphic/Style';
+import Element from 'zrender/src/Element';
 
 
 var PI = Math.PI;
 
+type AxisIndexKey = 'xAxisIndex' | 'yAxisIndex' | 'radiusAxisIndex'
+    | 'angleAxisIndex' | 'singleAxisIndex'
+
+type AxisEventData = {
+    componentType: string
+    componentIndex: number
+    targetType: 'axisName' | 'axisLabel'
+    name?: string
+    value?: string | number
+} & {
+    [key in AxisIndexKey]?: number
+}
+
+type LabelFormatterParams = {
+    componentType: string
+    name: string
+    $vars: ['name']
+} & {
+    [key in AxisIndexKey]?: number
+}
+
+type AxisLabelText = graphic.Text & {
+    __fullText: string
+    __truncatedText: string
+} & ECElement
+
+interface AxisBuilderCfg {
+    position?: number[]
+    rotation?: number
+    /**
+     * Used when nameLocation is 'middle' or 'center'.
+     * 1 | -1
+     */
+    nameDirection?: number
+    tickDirection?: number
+    labelDirection?: number
+    /**
+     * Usefull when onZero.
+     */
+    labelOffset?: number
+    /**
+     * default get from axisModel.
+     */
+    axisLabelShow?: boolean
+    /**
+     * default get from axisModel.
+     */
+    axisName?: string
+
+    axisNameAvailableWidth?: number
+    /**
+     * by degree, default get from axisModel.
+     */
+    labelRotate?: number
+
+    strokeContainThreshold?: number
+
+    nameTruncateMaxWidth?: number
+
+    silent?: boolean
+}
+
+interface TickCoord {
+    coord: number
+    tickValue?: number
+}
+
 /**
  * A final axis is translated and rotated from a "standard axis".
  * So opt.position and opt.rotation is required.
@@ -53,101 +123,132 @@ var PI = Math.PI;
  *
  * Do not need to consider axis 'inverse', which is auto processed by
  * axis extent.
- *
- * @param {module:zrender/container/Group} group
- * @param {Object} axisModel
- * @param {Object} opt Standard axis parameters.
- * @param {Array.<number>} opt.position [x, y]
- * @param {number} opt.rotation by radian
- * @param {number} [opt.nameDirection=1] 1 or -1 Used when nameLocation is 'middle' or 'center'.
- * @param {number} [opt.tickDirection=1] 1 or -1
- * @param {number} [opt.labelDirection=1] 1 or -1
- * @param {number} [opt.labelOffset=0] Usefull when onZero.
- * @param {string} [opt.axisLabelShow] default get from axisModel.
- * @param {string} [opt.axisName] default get from axisModel.
- * @param {number} [opt.axisNameAvailableWidth]
- * @param {number} [opt.labelRotate] by degree, default get from axisModel.
- * @param {number} [opt.strokeContainThreshold] Default label interval when label
- * @param {number} [opt.nameTruncateMaxWidth]
  */
-var AxisBuilder = function (axisModel, opt) {
+class AxisBuilder {
 
-    /**
-     * @readOnly
-     */
-    this.opt = opt;
+    axisModel: AxisBaseModel
 
-    /**
-     * @readOnly
-     */
-    this.axisModel = axisModel;
+    opt: AxisBuilderCfg
 
-    // Default value
-    defaults(
-        opt,
-        {
-            labelOffset: 0,
-            nameDirection: 1,
-            tickDirection: 1,
-            labelDirection: 1,
-            silent: true
-        }
-    );
+    readonly group = new graphic.Group()
 
-    /**
-     * @readOnly
-     */
-    this.group = new graphic.Group();
+    private _transformGroup: graphic.Group
 
-    // FIXME Not use a seperate text group?
-    var dumbGroup = new graphic.Group({
-        position: opt.position.slice(),
-        rotation: opt.rotation
-    });
+    constructor(axisModel: AxisBaseModel, opt?: AxisBuilderCfg) {
 
-    // this.group.add(dumbGroup);
-    // this._dumbGroup = dumbGroup;
+        this.opt = opt;
 
-    dumbGroup.updateTransform();
-    this._transform = dumbGroup.transform;
+        this.axisModel = axisModel;
 
-    this._dumbGroup = dumbGroup;
-};
+        // Default value
+        defaults(
+            opt,
+            {
+                labelOffset: 0,
+                nameDirection: 1,
+                tickDirection: 1,
+                labelDirection: 1,
+                silent: true
+            } as AxisBuilderCfg
+        );
+
+
+        // FIXME Not use a seperate text group?
+        var transformGroup = new graphic.Group({
+            position: opt.position.slice(),
+            rotation: opt.rotation
+        });
 
-AxisBuilder.prototype = {
+        // this.group.add(transformGroup);
+        // this._transformGroup = transformGroup;
 
-    constructor: AxisBuilder,
+        transformGroup.updateTransform();
 
-    hasBuilder: function (name) {
+        this._transformGroup = transformGroup;
+    }
+
+    hasBuilder(name: keyof typeof builders) {
         return !!builders[name];
-    },
+    }
 
-    add: function (name) {
-        builders[name].call(this);
-    },
+    add(name: keyof typeof builders) {
+        builders[name](this.opt, this.axisModel, this.group, this._transformGroup);
+    }
 
-    getGroup: function () {
+    getGroup() {
         return this.group;
     }
 
+    static innerTextLayout(axisRotation: number, textRotation: number, direction: number) {
+        var rotationDiff = remRadian(textRotation - axisRotation);
+        var textAlign;
+        var textVerticalAlign;
+
+        if (isRadianAroundZero(rotationDiff)) { // Label is parallel with axis line.
+            textVerticalAlign = direction > 0 ? 'top' : 'bottom';
+            textAlign = 'center';
+        }
+        else if (isRadianAroundZero(rotationDiff - PI)) { // Label is inverse parallel with axis line.
+            textVerticalAlign = direction > 0 ? 'bottom' : 'top';
+            textAlign = 'center';
+        }
+        else {
+            textVerticalAlign = 'middle';
+
+            if (rotationDiff > 0 && rotationDiff < PI) {
+                textAlign = direction > 0 ? 'right' : 'left';
+            }
+            else {
+                textAlign = direction > 0 ? 'left' : 'right';
+            }
+        }
+
+        return {
+            rotation: rotationDiff,
+            textAlign: textAlign as ZRTextAlign,
+            textVerticalAlign: textVerticalAlign as ZRTextVerticalAlign
+        };
+    }
+
+    static makeAxisEventDataBase(axisModel: AxisBaseModel) {
+        var eventData = {
+            componentType: axisModel.mainType,
+            componentIndex: axisModel.componentIndex
+        } as AxisEventData;
+        eventData[axisModel.mainType + 'Index' as AxisIndexKey] = axisModel.componentIndex;
+        return eventData;
+    }
+
+    static isLabelSilent(axisModel: AxisBaseModel): boolean {
+        var tooltipOpt = axisModel.get('tooltip');
+        return axisModel.get('silent')
+            // Consider mouse cursor, add these restrictions.
+            || !(
+                axisModel.get('triggerEvent') || (tooltipOpt && tooltipOpt.show)
+            );
+    }
 };
 
-var builders = {
+interface AxisElementsBuilder {
+    (
+        opt: AxisBuilderCfg,
+        axisModel: AxisBaseModel,
+        group: graphic.Group,
+        transformGroup: graphic.Group
+    ):void
+}
 
-    /**
-     * @private
-     */
-    axisLine: function () {
-        var opt = this.opt;
-        var axisModel = this.axisModel;
+var builders: Record<'axisLine' | 'axisTickLabel' | 'axisName', AxisElementsBuilder> = {
 
-        if (!axisModel.get('axisLine.show')) {
+    axisLine(opt, axisModel, group, transformGroup) {
+
+        if (!axisModel.get(['axisLine', 'show'])) {
             return;
         }
 
-        var extent = this.axisModel.axis.getExtent();
+        var extent = axisModel.axis.getExtent();
 
-        var matrix = this._transform;
+        var matrix = transformGroup.transform;
         var pt1 = [extent[0], 0];
         var pt2 = [extent[1], 0];
         if (matrix) {
@@ -159,12 +260,11 @@ var builders = {
             {
                 lineCap: 'round'
             },
-            axisModel.getModel('axisLine.lineStyle').getLineStyle()
+            axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle()
         );
 
-        this.group.add(new graphic.Line({
+        const line = new graphic.Line({
             // Id for animation
-            anid: 'line',
             subPixelOptimize: true,
             shape: {
                 x1: pt1[0],
@@ -176,12 +276,14 @@ var builders = {
             strokeContainThreshold: opt.strokeContainThreshold || 5,
             silent: true,
             z2: 1
-        }));
+        });
+        line.anid = 'line';
+        group.add(line);
 
-        var arrows = axisModel.get('axisLine.symbol');
-        var arrowSize = axisModel.get('axisLine.symbolSize');
+        var arrows = axisModel.get(['axisLine', 'symbol']);
+        var arrowSize = axisModel.get(['axisLine', 'symbolSize']);
 
-        var arrowOffset = axisModel.get('axisLine.symbolOffset') || 0;
+        var arrowOffset = axisModel.get(['axisLine', 'symbolOffset']) || 0;
         if (typeof arrowOffset === 'number') {
             arrowOffset = [arrowOffset, arrowOffset];
         }
@@ -235,33 +337,23 @@ var builders = {
                         silent: true,
                         z2: 11
                     });
-                    this.group.add(symbol);
+                    group.add(symbol);
                 }
-            }, this);
+            });
         }
     },
 
-    /**
-     * @private
-     */
-    axisTickLabel: function () {
-        var axisModel = this.axisModel;
-        var opt = this.opt;
+    axisTickLabel(opt, axisModel, group, transformGroup) {
 
-        var ticksEls = buildAxisMajorTicks(this, axisModel, opt);
-        var labelEls = buildAxisLabel(this, axisModel, opt);
+        var ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt.tickDirection);
+        var labelEls = buildAxisLabel(group, transformGroup, axisModel, opt);
 
         fixMinMaxLabelShow(axisModel, labelEls, ticksEls);
 
-        buildAxisMinorTicks(this, axisModel, opt);
+        buildAxisMinorTicks(group, transformGroup, axisModel, opt.tickDirection);
     },
 
-    /**
-     * @private
-     */
-    axisName: function () {
-        var opt = this.opt;
-        var axisModel = this.axisModel;
+    axisName(opt, axisModel, group, transformGroup) {
         var name = retrieve(opt.axisName, axisModel.get('name'));
 
         if (!name) {
@@ -273,7 +365,7 @@ var builders = {
         var textStyleModel = axisModel.getModel('nameTextStyle');
         var gap = axisModel.get('nameGap') || 0;
 
-        var extent = this.axisModel.axis.getExtent();
+        var extent = axisModel.axis.getExtent();
         var gapSignal = extent[0] > extent[1] ? -1 : 1;
         var pos = [
             nameLocation === 'start'
@@ -295,7 +387,7 @@ var builders = {
         var axisNameAvailableWidth;
 
         if (isNameLocationCenter(nameLocation)) {
-            labelLayout = innerTextLayout(
+            labelLayout = AxisBuilder.innerTextLayout(
                 opt.rotation,
                 nameRotation != null ? nameRotation : opt.rotation, // Adapt to axis.
                 nameDirection
@@ -303,7 +395,7 @@ var builders = {
         }
         else {
             labelLayout = endTextLayout(
-                opt, nameLocation, nameRotation || 0, extent
+                opt.rotation, nameLocation, nameRotation || 0, extent
             );
 
             axisNameAvailableWidth = opt.axisNameAvailableWidth;
@@ -334,40 +426,38 @@ var builders = {
         var tooltipOpt = axisModel.get('tooltip', true);
 
         var mainType = axisModel.mainType;
-        var formatterParams = {
+        var formatterParams: LabelFormatterParams = {
             componentType: mainType,
             name: name,
             $vars: ['name']
         };
-        formatterParams[mainType + 'Index'] = axisModel.componentIndex;
+        formatterParams[mainType + 'Index' as AxisIndexKey] = axisModel.componentIndex;
 
         var textEl = new graphic.Text({
-            // Id for animation
-            anid: 'name',
-
-            __fullText: name,
-            __truncatedText: truncatedText,
-
             position: pos,
             rotation: labelLayout.rotation,
-            silent: isLabelSilent(axisModel),
-            z2: 1,
-            tooltip: (tooltipOpt && tooltipOpt.show)
-                ? extend({
-                    content: name,
-                    formatter: function () {
-                        return name;
-                    },
-                    formatterParams: formatterParams
-                }, tooltipOpt)
-                : null
-        });
+            silent: AxisBuilder.isLabelSilent(axisModel),
+            z2: 1
+        }) as AxisLabelText;
+        textEl.tooltip = (tooltipOpt && tooltipOpt.show)
+            ? extend({
+                content: name,
+                formatter() {
+                    return name;
+                },
+                formatterParams: formatterParams
+            }, tooltipOpt)
+            : null;
+        textEl.__fullText = name;
+        textEl.__truncatedText = truncatedText;
+        // Id for animation
+        textEl.anid = 'name';
 
         graphic.setTextStyle(textEl.style, textStyleModel, {
             text: truncatedText,
             textFont: textFont,
             textFill: textStyleModel.getTextColor()
-                || axisModel.get('axisLine.lineStyle.color'),
+                || axisModel.get(['axisLine', 'lineStyle', 'color']),
             textAlign: textStyleModel.get('align')
                 || labelLayout.textAlign,
             textVerticalAlign: textStyleModel.get('verticalAlign')
@@ -375,79 +465,29 @@ var builders = {
         });
 
         if (axisModel.get('triggerEvent')) {
-            textEl.eventData = makeAxisEventDataBase(axisModel);
-            textEl.eventData.targetType = 'axisName';
-            textEl.eventData.name = name;
+            var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
+            eventData.targetType = 'axisName';
+            eventData.name = name;
+            graphic.getECData(textEl).eventData = eventData;
         }
 
         // FIXME
-        this._dumbGroup.add(textEl);
+        transformGroup.add(textEl);
         textEl.updateTransform();
 
-        this.group.add(textEl);
+        group.add(textEl);
 
         textEl.decomposeTransform();
     }
 
 };
 
-var makeAxisEventDataBase = AxisBuilder.makeAxisEventDataBase = function (axisModel) {
-    var eventData = {
-        componentType: axisModel.mainType,
-        componentIndex: axisModel.componentIndex
-    };
-    eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
-    return eventData;
-};
-
-/**
- * @public
- * @static
- * @param {Object} opt
- * @param {number} axisRotation in radian
- * @param {number} textRotation in radian
- * @param {number} direction
- * @return {Object} {
- *  rotation, // according to axis
- *  textAlign,
- *  textVerticalAlign
- * }
- */
-var innerTextLayout = AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
-    var rotationDiff = remRadian(textRotation - axisRotation);
-    var textAlign;
-    var textVerticalAlign;
-
-    if (isRadianAroundZero(rotationDiff)) { // Label is parallel with axis line.
-        textVerticalAlign = direction > 0 ? 'top' : 'bottom';
-        textAlign = 'center';
-    }
-    else if (isRadianAroundZero(rotationDiff - PI)) { // Label is inverse parallel with axis line.
-        textVerticalAlign = direction > 0 ? 'bottom' : 'top';
-        textAlign = 'center';
-    }
-    else {
-        textVerticalAlign = 'middle';
-
-        if (rotationDiff > 0 && rotationDiff < PI) {
-            textAlign = direction > 0 ? 'right' : 'left';
-        }
-        else {
-            textAlign = direction > 0 ? 'left' : 'right';
-        }
-    }
-
-    return {
-        rotation: rotationDiff,
-        textAlign: textAlign,
-        textVerticalAlign: textVerticalAlign
-    };
-};
-
-function endTextLayout(opt, textPosition, textRotate, extent) {
-    var rotationDiff = remRadian(textRotate - opt.rotation);
-    var textAlign;
-    var textVerticalAlign;
+function endTextLayout(
+    rotation: number, textPosition: 'start' | 'middle' | 'end', textRotate: number, extent: number[]
+) {
+    var rotationDiff = remRadian(textRotate - rotation);
+    var textAlign: ZRTextAlign;
+    var textVerticalAlign: ZRTextVerticalAlign;
     var inverse = extent[0] > extent[1];
     var onLeft = (textPosition === 'start' && !inverse)
         || (textPosition !== 'start' && inverse);
@@ -477,16 +517,11 @@ function endTextLayout(opt, textPosition, textRotate, extent) {
     };
 }
 
-var isLabelSilent = AxisBuilder.isLabelSilent = function (axisModel) {
-    var tooltipOpt = axisModel.get('tooltip');
-    return axisModel.get('silent')
-        // Consider mouse cursor, add these restrictions.
-        || !(
-            axisModel.get('triggerEvent') || (tooltipOpt && tooltipOpt.show)
-        );
-};
-
-function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
+function fixMinMaxLabelShow(
+    axisModel: AxisBaseModel,
+    labelEls: graphic.Text[],
+    tickEls: graphic.Line[]
+) {
     if (shouldShowAllLabels(axisModel.axis)) {
         return;
     }
@@ -494,8 +529,8 @@ function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
     // If min or max are user set, we need to check
     // If the tick on min(max) are overlap on their neighbour tick
     // If they are overlapped, we need to hide the min(max) tick label
-    var showMinLabel = axisModel.get('axisLabel.showMinLabel');
-    var showMaxLabel = axisModel.get('axisLabel.showMaxLabel');
+    var showMinLabel = axisModel.get(['axisLabel', 'showMinLabel']);
+    var showMaxLabel = axisModel.get(['axisLabel', 'showMaxLabel']);
 
     // FIXME
     // Have not consider onBand yet, where tick els is more than label els.
@@ -544,11 +579,14 @@ function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
     }
 }
 
-function ignoreEl(el) {
+function ignoreEl(el: Element) {
     el && (el.ignore = true);
 }
 
-function isTwoLabelOverlapped(current, next, labelLayout) {
+function isTwoLabelOverlapped(
+    current: graphic.Text,
+    next: graphic.Text
+) {
     // current and next has the same rotation.
     var firstRect = current && current.getBoundingRect().clone();
     var nextRect = next && next.getBoundingRect().clone();
@@ -568,15 +606,21 @@ function isTwoLabelOverlapped(current, next, labelLayout) {
     return firstRect.intersect(nextRect);
 }
 
-function isNameLocationCenter(nameLocation) {
+function isNameLocationCenter(nameLocation: string) {
     return nameLocation === 'middle' || nameLocation === 'center';
 }
 
 
-function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, aniid) {
+function createTicks(
+    ticksCoords: TickCoord[],
+    tickTransform: matrixUtil.MatrixArray,
+    tickEndCoord: number,
+    tickLineStyle: StyleProps,
+    anidPrefix: string
+) {
     var tickEls = [];
-    var pt1 = [];
-    var pt2 = [];
+    var pt1: number[] = [];
+    var pt2: number[] = [];
     for (var i = 0; i < ticksCoords.length; i++) {
         var tickCoord = ticksCoords[i].coord;
 
@@ -591,8 +635,6 @@ function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, an
         }
         // Tick line, Not use group transform to have better line draw
         var tickEl = new graphic.Line({
-            // Id for animation
-            anid: aniid + '_' + ticksCoords[i].tickValue,
             subPixelOptimize: true,
             shape: {
                 x1: pt1[0],
@@ -604,12 +646,18 @@ function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, an
             z2: 2,
             silent: true
         });
+        tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue;
         tickEls.push(tickEl);
     }
     return tickEls;
 }
 
-function buildAxisMajorTicks(axisBuilder, axisModel, opt) {
+function buildAxisMajorTicks(
+    group: graphic.Group,
+    transformGroup: graphic.Group,
+    axisModel: AxisBaseModel,
+    tickDirection: number
+) {
     var axis = axisModel.axis;
 
     var tickModel = axisModel.getModel('axisTick');
@@ -619,25 +667,30 @@ function buildAxisMajorTicks(axisBuilder, axisModel, opt) {
     }
 
     var lineStyleModel = tickModel.getModel('lineStyle');
-    var tickEndCoord = opt.tickDirection * tickModel.get('length');
+    var tickEndCoord = tickDirection * tickModel.get('length');
 
     var ticksCoords = axis.getTicksCoords();
 
-    var ticksEls = createTicks(ticksCoords, axisBuilder._transform, tickEndCoord, defaults(
+    var ticksEls = createTicks(ticksCoords, transformGroup.transform, tickEndCoord, defaults(
         lineStyleModel.getLineStyle(),
         {
-            stroke: axisModel.get('axisLine.lineStyle.color')
+            stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
         }
     ), 'ticks');
 
     for (var i = 0; i < ticksEls.length; i++) {
-        axisBuilder.group.add(ticksEls[i]);
+        group.add(ticksEls[i]);
     }
 
     return ticksEls;
 }
 
-function buildAxisMinorTicks(axisBuilder, axisModel, opt) {
+function buildAxisMinorTicks(
+    group: graphic.Group,
+    transformGroup: graphic.Group,
+    axisModel: AxisBaseModel,
+    tickDirection: number
+) {
     var axis = axisModel.axis;
 
     var minorTickModel = axisModel.getModel('minorTick');
@@ -652,31 +705,36 @@ function buildAxisMinorTicks(axisBuilder, axisModel, opt) {
     }
 
     var lineStyleModel = minorTickModel.getModel('lineStyle');
-    var tickEndCoord = opt.tickDirection * minorTickModel.get('length');
+    var tickEndCoord = tickDirection * minorTickModel.get('length');
 
     var minorTickLineStyle = defaults(
         lineStyleModel.getLineStyle(),
         defaults(
             axisModel.getModel('axisTick').getLineStyle(),
             {
-                stroke: axisModel.get('axisLine.lineStyle.color')
+                stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
             }
         )
     );
 
     for (var i = 0; i < minorTicksCoords.length; i++) {
         var minorTicksEls = createTicks(
-            minorTicksCoords[i], axisBuilder._transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i
+            minorTicksCoords[i], transformGroup.transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i
         );
         for (var k = 0; k < minorTicksEls.length; k++) {
-            axisBuilder.group.add(minorTicksEls[k]);
+            group.add(minorTicksEls[k]);
         }
     }
 }
 
-function buildAxisLabel(axisBuilder, axisModel, opt) {
+function buildAxisLabel(
+    group: graphic.Group,
+    transformGroup: graphic.Group,
+    axisModel: AxisBaseModel,
+    opt: AxisBuilderCfg
+) {
     var axis = axisModel.axis;
-    var show = retrieve(opt.axisLabelShow, axisModel.get('axisLabel.show'));
+    var show = retrieve(opt.axisLabelShow, axisModel.get(['axisLabel', 'show']));
 
     if (!show || axis.scale.isBlank()) {
         return;
@@ -691,11 +749,11 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
         retrieve(opt.labelRotate, labelModel.get('rotate')) || 0
     ) * PI / 180;
 
-    var labelLayout = innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
+    var labelLayout = AxisBuilder.innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
     var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true);
 
-    var labelEls = [];
-    var silent = isLabelSilent(axisModel);
+    var labelEls: graphic.Text[] = [];
+    var silent = AxisBuilder.isLabelSilent(axisModel);
     var triggerEvent = axisModel.get('triggerEvent');
 
     each(labels, function (labelItem, index) {
@@ -704,14 +762,17 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
         var rawLabel = labelItem.rawLabel;
 
         var itemLabelModel = labelModel;
-        if (rawCategoryData && rawCategoryData[tickValue] && rawCategoryData[tickValue].textStyle) {
-            itemLabelModel = new Model(
-                rawCategoryData[tickValue].textStyle, labelModel, axisModel.ecModel
-            );
+        if (rawCategoryData && rawCategoryData[tickValue]) {
+            const rawCategoryItem = rawCategoryData[tickValue];
+            if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
+                itemLabelModel = new Model(
+                    rawCategoryItem.textStyle, labelModel, axisModel.ecModel
+                );
+            }
         }
 
-        var textColor = itemLabelModel.getTextColor()
-            || axisModel.get('axisLine.lineStyle.color');
+        var textColor = itemLabelModel.getTextColor() as AxisBaseOption['axisLabel']['color']
+            || axisModel.get(['axisLine', 'lineStyle', 'color']);
 
         var tickCoord = axis.dataToCoord(tickValue);
         var pos = [
@@ -720,13 +781,12 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
         ];
 
         var textEl = new graphic.Text({
-            // Id for animation
-            anid: 'label_' + tickValue,
             position: pos,
             rotation: labelLayout.rotation,
             silent: silent,
             z2: 10
         });
+        textEl.anid = 'label_' + tickValue;
 
         graphic.setTextStyle(textEl.style, itemLabelModel, {
             text: formattedLabel,
@@ -756,17 +816,19 @@ function buildAxisLabel(axisBuilder, axisModel, opt) {
 
         // Pack data for mouse event
         if (triggerEvent) {
-            textEl.eventData = makeAxisEventDataBase(axisModel);
-            textEl.eventData.targetType = 'axisLabel';
-            textEl.eventData.value = rawLabel;
+            const eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
+            eventData.targetType = 'axisLabel';
+            eventData.value = rawLabel;
+
+            graphic.getECData(textEl).eventData = eventData;
         }
 
         // FIXME
-        axisBuilder._dumbGroup.add(textEl);
+        transformGroup.add(textEl);
         textEl.updateTransform();
 
         labelEls.push(textEl);
-        axisBuilder.group.add(textEl);
+        group.add(textEl);
 
         textEl.decomposeTransform();
 
diff --git a/src/component/axis/AxisView.ts b/src/component/axis/AxisView.ts
index 91a36c4..afb129c 100644
--- a/src/component/axis/AxisView.ts
+++ b/src/component/axis/AxisView.ts
@@ -17,34 +17,42 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import {__DEV__} from '../../config';
-import * as echarts from '../../echarts';
 import * as axisPointerModelHelper from '../axisPointer/modelHelper';
+import ComponentView from '../../view/Component';
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { Payload, Dictionary } from '../../util/types';
+import type BaseAxisPointer from '../axisPointer/BaseAxisPointer';
+
+var axisPointerClazz: Dictionary<AxisPointerConstructor> = {};
 
+interface AxisPointerConstructor {
+    new(): BaseAxisPointer
+}
 /**
  * Base class of AxisView.
  */
-var AxisView = echarts.extendComponentView({
+class AxisView extends ComponentView {
 
-    type: 'axis',
+    static type =  'axis'
+    type = AxisView.type
 
     /**
      * @private
      */
-    _axisPointer: null,
+    private _axisPointer: BaseAxisPointer
 
     /**
      * @protected
-     * @type {string}
      */
-    axisPointerClass: null,
+    axisPointerClass: string
 
     /**
      * @override
      */
-    render: function (axisModel, ecModel, api, payload) {
+    render(axisModel: AxisBaseModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload) {
         // FIXME
         // This process should proformed after coordinate systems updated
         // (axis scale updated), and should be performed each time update.
@@ -52,73 +60,69 @@ var AxisView = echarts.extendComponentView({
         // put a model-writing procedure in `view`.
         this.axisPointerClass && axisPointerModelHelper.fixValue(axisModel);
 
-        AxisView.superApply(this, 'render', arguments);
+        super.render.apply(this, arguments as any);
 
-        updateAxisPointer(this, axisModel, ecModel, api, payload, true);
-    },
+        this._doUpdateAxisPointerClass(axisModel, api, true);
+    }
 
     /**
      * Action handler.
-     * @public
-     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
-     * @param {module:echarts/model/Global} ecModel
-     * @param {module:echarts/ExtensionAPI} api
-     * @param {Object} payload
      */
-    updateAxisPointer: function (axisModel, ecModel, api, payload, force) {
-        updateAxisPointer(this, axisModel, ecModel, api, payload, false);
-    },
+    updateAxisPointer(
+        axisModel: AxisBaseModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        payload: Payload
+    ) {
+        this._doUpdateAxisPointerClass(axisModel, api, false);
+    }
 
     /**
      * @override
      */
-    remove: function (ecModel, api) {
+    remove(ecModel: GlobalModel, api: ExtensionAPI) {
         var axisPointer = this._axisPointer;
         axisPointer && axisPointer.remove(api);
-        AxisView.superApply(this, 'remove', arguments);
-    },
+    }
 
     /**
      * @override
      */
-    dispose: function (ecModel, api) {
-        disposeAxisPointer(this, api);
-        AxisView.superApply(this, 'dispose', arguments);
+    dispose(ecModel: GlobalModel, api: ExtensionAPI) {
+        this._disposeAxisPointer(api);
+        super.dispose.apply(this, arguments as any);
     }
 
-});
-
-function updateAxisPointer(axisView, axisModel, ecModel, api, payload, forceRender) {
-    var Clazz = AxisView.getAxisPointerClass(axisView.axisPointerClass);
-    if (!Clazz) {
-        return;
+    private _doUpdateAxisPointerClass(axisModel: AxisBaseModel, api: ExtensionAPI, forceRender?: boolean) {
+        var Clazz = AxisView.getAxisPointerClass(this.axisPointerClass);
+        if (!Clazz) {
+            return;
+        }
+        var axisPointerModel = axisPointerModelHelper.getAxisPointerModel(axisModel);
+        axisPointerModel
+            ? (this._axisPointer || (this._axisPointer = new Clazz()))
+                .render(axisModel, axisPointerModel, api, forceRender)
+            : this._disposeAxisPointer(api);
     }
-    var axisPointerModel = axisPointerModelHelper.getAxisPointerModel(axisModel);
-    axisPointerModel
-        ? (axisView._axisPointer || (axisView._axisPointer = new Clazz()))
-            .render(axisModel, axisPointerModel, api, forceRender)
-        : disposeAxisPointer(axisView, api);
-}
-
-function disposeAxisPointer(axisView, ecModel, api) {
-    var axisPointer = axisView._axisPointer;
-    axisPointer && axisPointer.dispose(ecModel, api);
-    axisView._axisPointer = null;
-}
 
-var axisPointerClazz = [];
+    private _disposeAxisPointer(api: ExtensionAPI) {
+        this._axisPointer && this._axisPointer.dispose(api);
+        this._axisPointer = null;
+    }
 
-AxisView.registerAxisPointerClass = function (type, clazz) {
-    if (__DEV__) {
-        if (axisPointerClazz[type]) {
-            throw new Error('axisPointer ' + type + ' exists');
+    static registerAxisPointerClass(type: string, clazz: AxisPointerConstructor) {
+        if (__DEV__) {
+            if (axisPointerClazz[type]) {
+                throw new Error('axisPointer ' + type + ' exists');
+            }
         }
-    }
-    axisPointerClazz[type] = clazz;
-};
+        axisPointerClazz[type] = clazz;
+    };
+
+    static getAxisPointerClass(type: string) {
+        return type && axisPointerClazz[type];
+    };
 
-AxisView.getAxisPointerClass = function (type) {
-    return type && axisPointerClazz[type];
-};
+}
 
 export default AxisView;
\ No newline at end of file
diff --git a/src/component/axis/CartesianAxisView.ts b/src/component/axis/CartesianAxisView.ts
index 29b8a1b..91f3f64 100644
--- a/src/component/axis/CartesianAxisView.ts
+++ b/src/component/axis/CartesianAxisView.ts
@@ -17,32 +17,39 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../../util/graphic';
 import AxisBuilder from './AxisBuilder';
 import AxisView from './AxisView';
 import * as cartesianAxisHelper from '../../coord/cartesian/cartesianAxisHelper';
 import {rectCoordAxisBuildSplitArea, rectCoordAxisHandleRemove} from './axisSplitHelper';
-
-var axisBuilderAttrs = [
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import CartesianAxisModel from '../../coord/cartesian/AxisModel';
+import GridModel from '../../coord/cartesian/GridModel';
+import ComponentView from '../../view/Component';
+import { Payload } from '../../util/types';
+
+const axisBuilderAttrs = [
     'axisLine', 'axisTickLabel', 'axisName'
-];
-var selfBuilderAttrs = [
+] as const;
+const selfBuilderAttrs = [
     'splitArea', 'splitLine', 'minorSplitLine'
-];
+] as const;
+
+class CartesianAxisView extends AxisView {
 
-var CartesianAxisView = AxisView.extend({
+    static type = 'cartesianAxis'
+    type = CartesianAxisView.type
 
-    type: 'cartesianAxis',
+    axisPointerClass = 'CartesianAxisPointer'
 
-    axisPointerClass: 'CartesianAxisPointer',
+    private _axisGroup: graphic.Group
 
     /**
      * @override
      */
-    render: function (axisModel, ecModel, api, payload) {
+    render(axisModel: CartesianAxisModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload) {
 
         this.group.removeAll();
 
@@ -66,26 +73,28 @@ var CartesianAxisView = AxisView.extend({
         this._axisGroup.add(axisBuilder.getGroup());
 
         zrUtil.each(selfBuilderAttrs, function (name) {
-            if (axisModel.get(name + '.show')) {
-                this['_' + name](axisModel, gridModel);
+            if (axisModel.get([name, 'show'])) {
+                axisElementBuilders[name](this, this._axisGroup, axisModel, gridModel);
             }
         }, this);
 
         graphic.groupTransition(oldAxisGroup, this._axisGroup, axisModel);
 
-        CartesianAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
-    },
+        super.render(axisModel, ecModel, api, payload);
+    }
 
-    remove: function () {
+    remove() {
         rectCoordAxisHandleRemove(this);
-    },
+    }
+}
 
-    /**
-     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
-     * @param {module:echarts/coord/cartesian/GridModel} gridModel
-     * @private
-     */
-    _splitLine: function (axisModel, gridModel) {
+interface AxisElementBuilder {
+    (axisView: CartesianAxisView, axisGroup: graphic.Group, axisModel: CartesianAxisModel, gridModel: GridModel): void
+}
+
+const axisElementBuilders: Record<typeof selfBuilderAttrs[number], AxisElementBuilder> = {
+
+    splitLine(axisView, axisGroup, axisModel, gridModel) {
         var axis = axisModel.axis;
 
         if (axis.scale.isBlank()) {
@@ -129,7 +138,7 @@ var CartesianAxisView = AxisView.extend({
 
             var colorIndex = (lineCount++) % lineColors.length;
             var tickValue = ticksCoords[i].tickValue;
-            this._axisGroup.add(new graphic.Line({
+            axisGroup.add(new graphic.Line({
                 anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
                 subPixelOptimize: true,
                 shape: {
@@ -146,12 +155,7 @@ var CartesianAxisView = AxisView.extend({
         }
     },
 
-    /**
-     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
-     * @param {module:echarts/coord/cartesian/GridModel} gridModel
-     * @private
-     */
-    _minorSplitLine: function (axisModel, gridModel) {
+    minorSplitLine(axisView, axisGroup, axisModel, gridModel) {
         var axis = axisModel.axis;
 
         var minorSplitLineModel = axisModel.getModel('minorSplitLine');
@@ -187,7 +191,7 @@ var CartesianAxisView = AxisView.extend({
                     p2[1] = tickCoord;
                 }
 
-                this._axisGroup.add(new graphic.Line({
+                axisGroup.add(new graphic.Line({
                     anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
                     subPixelOptimize: true,
                     shape: {
@@ -203,19 +207,21 @@ var CartesianAxisView = AxisView.extend({
         }
     },
 
-    /**
-     * @param {module:echarts/coord/cartesian/AxisModel} axisModel
-     * @param {module:echarts/coord/cartesian/GridModel} gridModel
-     * @private
-     */
-    _splitArea: function (axisModel, gridModel) {
-        rectCoordAxisBuildSplitArea(this, this._axisGroup, axisModel, gridModel);
+    splitArea(axisView, axisGroup, axisModel, gridModel) {
+        rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel);
     }
-});
-
-CartesianAxisView.extend({
-    type: 'xAxis'
-});
-CartesianAxisView.extend({
-    type: 'yAxis'
-});
+};
+
+class CartesianXAxisView extends CartesianAxisView {
+    static type = 'xAxis'
+    type = CartesianXAxisView.type
+}
+class CartesianYAxisView extends CartesianAxisView {
+    static type = 'yAxis'
+    type = CartesianXAxisView.type
+}
+
+ComponentView.registerClass(CartesianXAxisView);
+ComponentView.registerClass(CartesianYAxisView);
+
+export default CartesianAxisView;
\ No newline at end of file
diff --git a/src/component/axis/RadiusAxisView.ts b/src/component/axis/RadiusAxisView.ts
index 7817b34..4f224ee 100644
--- a/src/component/axis/RadiusAxisView.ts
+++ b/src/component/axis/RadiusAxisView.ts
@@ -17,27 +17,32 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../../util/graphic';
 import AxisBuilder from './AxisBuilder';
 import AxisView from './AxisView';
+import { RadiusAxisModel } from '../../coord/polar/AxisModel';
+import Polar from '../../coord/polar/Polar';
+import RadiusAxis from '../../coord/polar/RadiusAxis';
+import GlobalModel from '../../model/Global';
 
 var axisBuilderAttrs = [
     'axisLine', 'axisTickLabel', 'axisName'
-];
+] as const;
 var selfBuilderAttrs = [
     'splitLine', 'splitArea', 'minorSplitLine'
-];
+] as const;
+
+type TickCoord = ReturnType<RadiusAxis['getTicksCoords']>[number];
 
-export default AxisView.extend({
+class RadiusAxisView extends AxisView {
 
-    type: 'radiusAxis',
+    static readonly type = 'radiusAxis'
+    readonly type = RadiusAxisView.type
 
-    axisPointerClass: 'PolarAxisPointer',
+    axisPointerClass = 'PolarAxisPointer'
 
-    render: function (radiusAxisModel, ecModel) {
+    render(radiusAxisModel: RadiusAxisModel, ecModel: GlobalModel) {
         this.group.removeAll();
         if (!radiusAxisModel.get('show')) {
             return;
@@ -56,16 +61,36 @@ export default AxisView.extend({
         this.group.add(axisBuilder.getGroup());
 
         zrUtil.each(selfBuilderAttrs, function (name) {
-            if (radiusAxisModel.get(name + '.show') && !radiusAxis.scale.isBlank()) {
-                this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords);
+            if (radiusAxisModel.get([name, 'show']) && !radiusAxis.scale.isBlank()) {
+                axisElementBuilders[name](
+                    this.group,
+                    radiusAxisModel,
+                    polar,
+                    axisAngle,
+                    radiusExtent,
+                    ticksCoords,
+                    minorTicksCoords
+                );
             }
         }, this);
-    },
-
-    /**
-     * @private
-     */
-    _splitLine: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
+    }
+}
+
+interface AxisElementBuilder {
+    (
+        group: graphic.Group,
+        axisModel: RadiusAxisModel,
+        polar: Polar,
+        axisAngle: number,
+        radiusExtent: number[],
+        ticksCoords: TickCoord[],
+        minorTicksCoords?: TickCoord[][]
+    ): void
+}
+
+const axisElementBuilders: Record<typeof selfBuilderAttrs[number], AxisElementBuilder> = {
+
+    splitLine(group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
         var splitLineModel = radiusAxisModel.getModel('splitLine');
         var lineStyleModel = splitLineModel.getModel('lineStyle');
         var lineColors = lineStyleModel.get('color');
@@ -73,7 +98,7 @@ export default AxisView.extend({
 
         lineColors = lineColors instanceof Array ? lineColors : [lineColors];
 
-        var splitLines = [];
+        var splitLines: graphic.Circle[][] = [];
 
         for (var i = 0; i < ticksCoords.length; i++) {
             var colorIndex = (lineCount++) % lineColors.length;
@@ -90,7 +115,7 @@ export default AxisView.extend({
         // Simple optimization
         // Batching the lines if color are the same
         for (var i = 0; i < splitLines.length; i++) {
-            this.group.add(graphic.mergePath(splitLines[i], {
+            group.add(graphic.mergePath(splitLines[i], {
                 style: zrUtil.defaults({
                     stroke: lineColors[i % lineColors.length],
                     fill: null
@@ -100,10 +125,7 @@ export default AxisView.extend({
         }
     },
 
-    /**
-     * @private
-     */
-    _minorSplitLine: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) {
+    minorSplitLine(group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) {
         if (!minorTicksCoords.length) {
             return;
         }
@@ -111,7 +133,7 @@ export default AxisView.extend({
         var minorSplitLineModel = radiusAxisModel.getModel('minorSplitLine');
         var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
 
-        var lines = [];
+        var lines: graphic.Circle[] = [];
 
         for (var i = 0; i < minorTicksCoords.length; i++) {
             for (var k = 0; k < minorTicksCoords[i].length; k++) {
@@ -125,7 +147,7 @@ export default AxisView.extend({
             }
         }
 
-        this.group.add(graphic.mergePath(lines, {
+        group.add(graphic.mergePath(lines, {
             style: zrUtil.defaults({
                 fill: null
             }, lineStyleModel.getLineStyle()),
@@ -133,10 +155,7 @@ export default AxisView.extend({
         }));
     },
 
-    /**
-     * @private
-     */
-    _splitArea: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
+    splitArea(group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
         if (!ticksCoords.length) {
             return;
         }
@@ -148,7 +167,7 @@ export default AxisView.extend({
 
         areaColors = areaColors instanceof Array ? areaColors : [areaColors];
 
-        var splitAreas = [];
+        var splitAreas: graphic.Sector[][] = [];
 
         var prevRadius = ticksCoords[0].coord;
         for (var i = 1; i < ticksCoords.length; i++) {
@@ -171,7 +190,7 @@ export default AxisView.extend({
         // Simple optimization
         // Batching the lines if color are the same
         for (var i = 0; i < splitAreas.length; i++) {
-            this.group.add(graphic.mergePath(splitAreas[i], {
+            group.add(graphic.mergePath(splitAreas[i], {
                 style: zrUtil.defaults({
                     fill: areaColors[i % areaColors.length]
                 }, areaStyleModel.getAreaStyle()),
@@ -179,20 +198,22 @@ export default AxisView.extend({
             }));
         }
     }
-});
+};
 
 /**
  * @inner
  */
-function layoutAxis(polar, radiusAxisModel, axisAngle) {
+function layoutAxis(polar: Polar, radiusAxisModel: RadiusAxisModel, axisAngle: number) {
     return {
         position: [polar.cx, polar.cy],
         rotation: axisAngle / 180 * Math.PI,
-        labelDirection: -1,
-        tickDirection: -1,
-        nameDirection: 1,
+        labelDirection: -1 as const,
+        tickDirection: -1 as const,
+        nameDirection: 1 as const,
         labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'),
         // Over splitLine and splitArea
         z2: 1
     };
-}
\ No newline at end of file
+}
+
+AxisView.registerClass(RadiusAxisView);
\ No newline at end of file
diff --git a/src/component/axis/SingleAxisView.ts b/src/component/axis/SingleAxisView.ts
index db34cca..a50e87d 100644
--- a/src/component/axis/SingleAxisView.ts
+++ b/src/component/axis/SingleAxisView.ts
@@ -17,28 +17,33 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import AxisBuilder from './AxisBuilder';
 import * as graphic from '../../util/graphic';
 import * as singleAxisHelper from '../../coord/single/singleAxisHelper';
 import AxisView from './AxisView';
 import {rectCoordAxisBuildSplitArea, rectCoordAxisHandleRemove} from './axisSplitHelper';
+import SingleAxisModel from '../../coord/single/AxisModel';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { Payload } from '../../util/types';
 
 var axisBuilderAttrs = [
     'axisLine', 'axisTickLabel', 'axisName'
-];
+] as const;
+
+var selfBuilderAttrs = ['splitArea', 'splitLine'] as const;
 
-var selfBuilderAttrs = ['splitArea', 'splitLine'];
+class SingleAxisView extends AxisView {
 
-var SingleAxisView = AxisView.extend({
+    static readonly type = 'singleAxis'
+    readonly type = SingleAxisView.type
 
-    type: 'singleAxis',
+    private _axisGroup: graphic.Group
 
-    axisPointerClass: 'SingleAxisPointer',
+    axisPointerClass = 'SingleAxisPointer'
 
-    render: function (axisModel, ecModel, api, payload) {
+    render(axisModel: SingleAxisModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload) {
 
         var group = this.group;
 
@@ -57,21 +62,28 @@ var SingleAxisView = AxisView.extend({
         group.add(axisBuilder.getGroup());
 
         zrUtil.each(selfBuilderAttrs, function (name) {
-            if (axisModel.get(name + '.show')) {
-                this['_' + name](axisModel);
+            if (axisModel.get([name, 'show'])) {
+                axisElementBuilders[name](this, this.group, this._axisGroup, axisModel);
             }
         }, this);
 
         graphic.groupTransition(oldAxisGroup, this._axisGroup, axisModel);
 
-        SingleAxisView.superCall(this, 'render', axisModel, ecModel, api, payload);
-    },
+        super.render(axisModel, ecModel, api, payload);
+    }
 
-    remove: function () {
+    remove() {
         rectCoordAxisHandleRemove(this);
-    },
+    }
+}
+
+interface AxisElementBuilder {
+    (axisView: SingleAxisView, group: graphic.Group, axisGroup: graphic.Group, axisModel: SingleAxisModel): void
+}
+
+const axisElementBuilders: Record<typeof selfBuilderAttrs[number], AxisElementBuilder> = {
 
-    _splitLine: function (axisModel) {
+    splitLine(axisView, group, axisGroup, axisModel) {
         var axis = axisModel.axis;
 
         if (axis.scale.isBlank()) {
@@ -88,7 +100,7 @@ var SingleAxisView = AxisView.extend({
         var gridRect = axisModel.coordinateSystem.getRect();
         var isHorizontal = axis.isHorizontal();
 
-        var splitLines = [];
+        var splitLines: graphic.Line[][] = [];
         var lineCount = 0;
 
         var ticksCoords = axis.getTicksCoords({
@@ -130,7 +142,7 @@ var SingleAxisView = AxisView.extend({
         }
 
         for (var i = 0; i < splitLines.length; ++i) {
-            this.group.add(graphic.mergePath(splitLines[i], {
+            group.add(graphic.mergePath(splitLines[i], {
                 style: {
                     stroke: lineColors[i % lineColors.length],
                     lineDash: lineStyleModel.getLineDash(lineWidth),
@@ -141,9 +153,9 @@ var SingleAxisView = AxisView.extend({
         }
     },
 
-    _splitArea: function (axisModel) {
-        rectCoordAxisBuildSplitArea(this, this._axisGroup, axisModel, axisModel);
+    splitArea(axisView, group, axisGroup, axisModel) {
+        rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, axisModel);
     }
-});
+};
 
 export default SingleAxisView;
diff --git a/src/component/axis/axisSplitHelper.ts b/src/component/axis/axisSplitHelper.ts
index 555bcc0..00ad642 100644
--- a/src/component/axis/axisSplitHelper.ts
+++ b/src/component/axis/axisSplitHelper.ts
@@ -17,20 +17,34 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../../util/graphic';
-
-
-export function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel) {
+import { makeInner } from '../../util/model';
+import GridModel from '../../coord/cartesian/GridModel';
+import type SingleAxisView from './SingleAxisView';
+import type CartesianAxisView from './CartesianAxisView';
+import type SingleAxisModel from '../../coord/single/AxisModel';
+import type CartesianAxisModel from '../../coord/cartesian/AxisModel';
+
+const inner = makeInner<{
+    // Hash map of color index
+    splitAreaColors: zrUtil.HashMap<number>
+}>();
+
+export function rectCoordAxisBuildSplitArea(
+    axisView: SingleAxisView | CartesianAxisView,
+    axisGroup: graphic.Group,
+    axisModel: SingleAxisModel | CartesianAxisModel,
+    gridModel: GridModel | SingleAxisModel
+) {
     var axis = axisModel.axis;
 
     if (axis.scale.isBlank()) {
         return;
     }
 
-    var splitAreaModel = axisModel.getModel('splitArea');
+    // TODO: TYPE
+    var splitAreaModel = (axisModel as CartesianAxisModel).getModel('splitArea');
     var areaStyleModel = splitAreaModel.getModel('areaStyle');
     var areaColors = areaStyleModel.get('color');
 
@@ -48,8 +62,8 @@ export function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, grid
     // For Making appropriate splitArea animation, the color and anid
     // should be corresponding to previous one if possible.
     var areaColorsLen = areaColors.length;
-    var lastSplitAreaColors = axisView.__splitAreaColors;
-    var newSplitAreaColors = zrUtil.createHashMap();
+    var lastSplitAreaColors = inner(axisView).splitAreaColors;
+    var newSplitAreaColors = zrUtil.createHashMap<number>();
     var colorIndex = 0;
     if (lastSplitAreaColors) {
         for (var i = 0; i < ticksCoords.length; i++) {
@@ -108,9 +122,9 @@ export function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, grid
         colorIndex = (colorIndex + 1) % areaColorsLen;
     }
 
-    axisView.__splitAreaColors = newSplitAreaColors;
+    inner(axisView).splitAreaColors = newSplitAreaColors;
 }
 
-export function rectCoordAxisHandleRemove(axisView) {
-    axisView.__splitAreaColors = null;
+export function rectCoordAxisHandleRemove(axisView: SingleAxisView | CartesianAxisView) {
+    inner(axisView).splitAreaColors = null;
 }
diff --git a/src/component/axisPointer/PolarAxisPointer.ts b/src/component/axisPointer/PolarAxisPointer.ts
index 4760706..c15f486 100644
--- a/src/component/axisPointer/PolarAxisPointer.ts
+++ b/src/component/axisPointer/PolarAxisPointer.ts
@@ -23,7 +23,12 @@ 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 {OptionDataValue,
+    ScaleDataValue,
+    CommonAxisPointerOption,
+    ZRTextAlign,
+    ZRTextVerticalAlign
+} from '../../util/types';
 import { PolarAxisModel } from '../../coord/polar/AxisModel';
 import ExtensionAPI from '../../ExtensionAPI';
 import Polar from '../../coord/polar/Polar';
@@ -93,8 +98,8 @@ function getLabelPosition(
     axisAngle = axisAngle / 180 * Math.PI;
     var radiusExtent = polar.getRadiusAxis().getExtent();
     var position;
-    var align;
-    var verticalAlign;
+    var align: ZRTextAlign;
+    var verticalAlign: ZRTextVerticalAlign;
 
     if (axis.dim === 'radius') {
         var transform = matrix.create();
diff --git a/src/component/axisPointer/viewHelper.ts b/src/component/axisPointer/viewHelper.ts
index b26d2da..773ea97 100644
--- a/src/component/axisPointer/viewHelper.ts
+++ b/src/component/axisPointer/viewHelper.ts
@@ -43,7 +43,10 @@ interface LayoutInfo {
     position: VectorArray
     rotation: number
     labelOffset?: number
-    labelDirection?: -1 | 1
+    /**
+     * 1 | -1
+     */
+    labelDirection?: number
     labelMargin?: number
 }
 
diff --git a/src/component/gridSimple.ts b/src/component/gridSimple.ts
index 3e25269..552a96c 100644
--- a/src/component/gridSimple.ts
+++ b/src/component/gridSimple.ts
@@ -17,22 +17,22 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as echarts from '../echarts';
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../util/graphic';
 
-import '../coord/cartesian/Grid';
-import '../coord/cartesian/GridModel';
 import './axis';
+import ComponentView from '../view/Component';
+import GlobalModel from '../model/Global';
+import GridModel from '../coord/cartesian/GridModel';
+import ComponentModel from '../model/Component';
 
 // Grid view
-echarts.extendComponentView({
-
-    type: 'grid',
+class GridView extends ComponentView {
+    static readonly type = 'grid'
+    readonly type = 'grid'
 
-    render: function (gridModel, ecModel) {
+    render(gridModel: GridModel, ecModel: GlobalModel) {
         this.group.removeAll();
         if (gridModel.get('show')) {
             this.group.add(new graphic.Rect({
@@ -46,7 +46,10 @@ echarts.extendComponentView({
         }
     }
 
-});
+}
+
+ComponentView.registerClass(GridView);
+ComponentModel.registerClass(GridModel);
 
 echarts.registerPreprocessor(function (option) {
     // Only create grid when need
diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts
index 1cdf2bf..e32181b 100644
--- a/src/coord/axisCommonTypes.ts
+++ b/src/coord/axisCommonTypes.ts
@@ -19,16 +19,17 @@
 
 import {
     TextCommonOption, LineStyleOption, OrdinalRawValue, ZRColor,
-    AreaStyleOption, ComponentOption, OptionDataValue
+    AreaStyleOption, ComponentOption, OptionDataValue, ColorString,
+    AnimationOptionMixin, Dictionary
 } from '../util/types';
-import { Dictionary } from 'zrender/src/core/types';
 
 
 export var AXIS_TYPES = {value: 1, category: 1, time: 1, log: 1} as const;
 export type OptionAxisType = keyof typeof AXIS_TYPES;
 
 
-export interface AxisBaseOption extends ComponentOption {
+export interface AxisBaseOption extends ComponentOption,
+    AnimationOptionMixin {  // Support transition animation
     type?: OptionAxisType;
     show?: boolean;
     // Inverse the axis.
@@ -158,7 +159,7 @@ interface AxisTickOption {
     interval?: 'auto' | number | ((index: number, value: string) => boolean)
 }
 
-interface AxisLabelOption extends TextCommonOption {
+interface AxisLabelOption extends Omit<TextCommonOption, 'color'> {
     show?: boolean,
     // Whether axisLabel is inside the grid or outside the grid.
     inside?: boolean,
@@ -175,6 +176,9 @@ interface AxisLabelOption extends TextCommonOption {
     // [Properties below only for 'category' axis]:
 
     interval?: 'auto' | number | ((index: number, value: string) => boolean)
+
+    // Color can be callback
+    color?: ColorString | ((value?: string | number, index?: number) => ColorString)
 }
 
 interface MinorTickOption {
@@ -200,5 +204,5 @@ interface SplitAreaOption {
     show?: boolean,
     interval?: 'auto' | number | ((index:number, value: string) => boolean)
     // colors will display in turn
-    areaStyle?: AreaStyleOption<ZRColor | ZRColor[]>
+    areaStyle?: AreaStyleOption<ZRColor[]>
 }
\ No newline at end of file
diff --git a/src/coord/single/singleAxisHelper.ts b/src/coord/single/singleAxisHelper.ts
index a2fb43e..eb3d899 100644
--- a/src/coord/single/singleAxisHelper.ts
+++ b/src/coord/single/singleAxisHelper.ts
@@ -24,9 +24,9 @@ interface LayoutResult {
     position: [number, number],
     rotation: number
     labelRotation: number
-    labelDirection: 1 | -1
-    tickDirection: 1 | -1
-    nameDirection: 1 | -1
+    labelDirection: number  // 1 | -1
+    tickDirection: number
+    nameDirection: number
     z2: number
 }
 
@@ -68,11 +68,11 @@ export function layout(axisModel: SingleAxisModel, opt?: {
         layout.nameDirection = directionMap[axisPosition];
 
     if (axisModel.get(['axisTick', 'inside'])) {
-        layout.tickDirection = -layout.tickDirection as -1 | 1;
+        layout.tickDirection = -layout.tickDirection;
     }
 
     if (zrUtil.retrieve(opt.labelInside, axisModel.get(['axisLabel', 'inside']))) {
-        layout.labelDirection = -layout.labelDirection as -1 | 1;
+        layout.labelDirection = -layout.labelDirection;
     }
 
     var labelRotation = opt.rotate;
diff --git a/src/model/Component.ts b/src/model/Component.ts
index c918474..31c3782 100644
--- a/src/model/Component.ts
+++ b/src/model/Component.ts
@@ -160,7 +160,7 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
         }
     }
 
-    mergeOption(option: ComponentOption, ecModel: GlobalModel): void {
+    mergeOption(option: Opt, ecModel: GlobalModel): void {
         zrUtil.merge(this.option, option, true);
 
         var layoutMode = layout.fetchLayoutMode(this);
@@ -174,7 +174,7 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
     }
 
     // Hooker after init or mergeOption
-    optionUpdated(newCptOption: ComponentOption, isInit: boolean): void {}
+    optionUpdated(newCptOption: Opt, isInit: boolean): void {}
 
     /**
      * [How to declare defaultOption]:
@@ -230,7 +230,7 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
      * })
      * ```
      */
-    getDefaultOption(): ComponentOption {
+    getDefaultOption(): Opt {
         var ctor = this.constructor;
 
         // If using class declaration, it is different to travel super class
@@ -258,7 +258,7 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
             }
             fields.defaultOption = defaultOption;
         }
-        return fields.defaultOption;
+        return fields.defaultOption as Opt;
     }
 
     getReferringComponents(mainType: ComponentMainType): ComponentModel[] {
diff --git a/src/model/mixin/textStyle.ts b/src/model/mixin/textStyle.ts
index a06018d..193b820 100644
--- a/src/model/mixin/textStyle.ts
+++ b/src/model/mixin/textStyle.ts
@@ -30,6 +30,7 @@ class TextStyleMixin {
     /**
      * Get color property or get color from option.textStyle.color
      */
+    // TODO Callback
     getTextColor(this: Model, isEmphasis?: boolean): ColorString {
         var ecModel = this.ecModel;
         return this.getShallow('color')


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