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/01 15:34:35 UTC

[incubator-echarts] branch typescript updated: ts: add types for bar. upgrade ts version to 3.8

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 7fe605c  ts: add types for bar. upgrade ts version to 3.8
7fe605c is described below

commit 7fe605cfd2e4ccc1a668f783a14a15b80a0f5acd
Author: pissang <bm...@gmail.com>
AuthorDate: Sun Mar 1 23:33:58 2020 +0800

    ts: add types for bar. upgrade ts version to 3.8
---
 .vscode/settings.json                    |   3 +
 package-lock.json                        |  43 +---
 package.json                             |   2 +-
 src/chart/bar/BarSeries.ts               |  91 ++++++--
 src/chart/bar/BarView.ts                 | 380 +++++++++++++++++++------------
 src/chart/bar/BaseBarSeries.ts           | 102 ++++++---
 src/chart/bar/PictorialBarSeries.ts      | 125 ++++++++--
 src/chart/bar/PictorialBarView.ts        | 336 ++++++++++++++++++++-------
 src/chart/bar/barItemStyle.ts            |  19 +-
 src/chart/bar/helper.ts                  |  23 +-
 src/component/axisPointer/axisTrigger.ts |   6 +-
 src/component/helper/RoamController.ts   |   1 -
 src/component/visualMap/PiecewiseView.ts |  40 ++--
 src/coord/cartesian/Cartesian2D.ts       |   2 +-
 src/data/List.ts                         |   1 -
 src/echarts.ts                           |   4 +-
 src/layout/barGrid.ts                    | 227 ++++++++++--------
 src/layout/barPolar.ts                   |  74 +++---
 src/model/Global.ts                      |   2 +-
 src/model/Series.ts                      |  16 +-
 src/util/graphic.ts                      |  11 +-
 src/util/symbol.ts                       |   4 +-
 src/util/throttle.ts                     |   2 +-
 src/util/types.ts                        |  21 +-
 src/view/Chart.ts                        | 101 ++++----
 src/visual/visualSolution.ts             |   9 +-
 26 files changed, 1073 insertions(+), 572 deletions(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..c7c1623
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+    "typescript.tsdk": "./node_modules/typescript/lib"
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index fb9a8ab..94dc284 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -742,6 +742,12 @@
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
+        },
+        "typescript": {
+          "version": "3.7.5",
+          "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz",
+          "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==",
+          "dev": true
         }
       }
     },
@@ -6985,37 +6991,6 @@
         "resolve": "^1.1.6"
       }
     },
-    "rollup-plugin-progress": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/rollup-plugin-progress/-/rollup-plugin-progress-1.1.1.tgz",
-      "integrity": "sha512-RIs2bnk/O2fylGN0F2w38U4PhAGIt8/N2noZ3i2tDOF0qg0PPZLKMMFp24MQUyND/w9nu61DRSanwpXOoJhxIA==",
-      "dev": true,
-      "requires": {
-        "chalk": "^2.4.2"
-      },
-      "dependencies": {
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
-      }
-    },
     "rollup-plugin-typescript2": {
       "version": "0.25.3",
       "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.25.3.tgz",
@@ -8023,9 +7998,9 @@
       }
     },
     "typescript": {
-      "version": "3.7.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz",
-      "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==",
+      "version": "3.8.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
+      "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
       "dev": true
     },
     "uglify-js": {
diff --git a/package.json b/package.json
index 10ccec3..e5dd487 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,6 @@
     "serve-handler": "6.1.1",
     "slugify": "1.3.4",
     "socket.io": "2.2.0",
-    "typescript": "3.7.4"
+    "typescript": "^3.8.3"
   }
 }
diff --git a/src/chart/bar/BarSeries.ts b/src/chart/bar/BarSeries.ts
index c4cd150..8ef8334 100644
--- a/src/chart/bar/BarSeries.ts
+++ b/src/chart/bar/BarSeries.ts
@@ -17,32 +17,92 @@
 * under the License.
 */
 
-// @ts-nocheck
+import BaseBarSeriesModel, {BaseBarSeriesOption} from './BaseBarSeries';
+import SeriesModel from '../../model/Series';
+import { ItemStyleOption, OptionDataValue, LabelOption } from '../../util/types';
+import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
+import type Polar from '../../coord/polar/Polar';
 
-import BaseBarSeries from './BaseBarSeries';
+type BarDataValue = OptionDataValue | OptionDataValue[]
 
-export default BaseBarSeries.extend({
+export interface BarItemStyleOption extends ItemStyleOption {
+    /**
+     * Border radius is not supported for bar on polar
+     */
+    barBorderRadius?: number | number[]
+}
+export interface BarDataItemOption {
+    name?: string
+
+    value?: BarDataValue
+
+    itemStyle?: BarItemStyleOption
+    label?: LabelOption
+
+    cursor?: string
+
+    emphasis?: {
+        itemStyle?: BarItemStyleOption
+        label?: LabelOption
+    }
+}
+
+export interface BarSeriesOption extends BaseBarSeriesOption {
+    coordinateSystem?: 'cartesian2d' | 'polar'
+
+    clip?: boolean
+
+    stack?: string
+
+    /**
+     * If use caps on two sides of bars
+     * Only available on tangential polar bar
+     */
+    roundCap?: boolean
+
+    showBackground?: boolean
 
-    type: 'series.bar',
+    backgroundStyle?: ItemStyleOption & {
+        borderRadius?: number | number[]
+    }
+
+    data?: (BarDataItemOption | BarDataValue)[]
+
+    label?: LabelOption
+
+    itemStyle?: BarItemStyleOption
+
+    emphasis?: {
+        label?: LabelOption
+        itemStyle?: BarItemStyleOption
+    }
+
+}
 
-    dependencies: ['grid', 'polar'],
+class BarSeriesModel extends BaseBarSeriesModel<BarSeriesOption> {
+    static type = 'series.bar'
+    type = BarSeriesModel.type
 
-    brushSelector: 'rect',
+    static dependencies = ['grid', 'polar']
+
+    readonly brushSelector = 'rect'
+
+    coordinateSystem: Cartesian2D | Polar
 
     /**
      * @override
      */
-    getProgressive: function () {
+    getProgressive() {
         // Do not support progressive in normal mode.
         return this.get('large')
             ? this.get('progressive')
             : false;
-    },
+    }
 
     /**
      * @override
      */
-    getProgressiveThreshold: function () {
+    getProgressiveThreshold() {
         // Do not support progressive in normal mode.
         var progressiveThreshold = this.get('progressiveThreshold');
         var largeThreshold = this.get('largeThreshold');
@@ -50,15 +110,13 @@ export default BaseBarSeries.extend({
             progressiveThreshold = largeThreshold;
         }
         return progressiveThreshold;
-    },
+    }
 
-    defaultOption: {
+    static defaultOption: BarSeriesOption = {
         // If clipped
         // Only available on cartesian2d
         clip: true,
 
-        // If use caps on two sides of bars
-        // Only available on tangential polar bar
         roundCap: false,
 
         showBackground: false,
@@ -75,4 +133,9 @@ export default BaseBarSeries.extend({
             opacity: 1
         }
     }
-});
+
+}
+
+SeriesModel.registerClass(BarSeriesModel);
+
+export default BarSeriesModel;
\ No newline at end of file
diff --git a/src/chart/bar/BarView.ts b/src/chart/bar/BarView.ts
index 23a5d64..20d8c8f 100644
--- a/src/chart/bar/BarView.ts
+++ b/src/chart/bar/BarView.ts
@@ -17,31 +17,47 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import {__DEV__} from '../../config';
-import * as echarts from '../../echarts';
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../../util/graphic';
 import {setLabel} from './helper';
-import Model from '../../model/Model';
-import barItemStyle from './barItemStyle';
-import Path from 'zrender/src/graphic/Path';
+import {getBarItemStyle} from './barItemStyle';
+import Path, { PathProps } from 'zrender/src/graphic/Path';
 import Group from 'zrender/src/container/Group';
 import {throttle} from '../../util/throttle';
 import {createClipPath} from '../helper/createClipPathFromCoordSys';
 import Sausage from '../../util/shape/sausage';
+import ChartView from '../../view/Chart';
+import List from '../../data/List';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { StageHandlerProgressParams, ECElement, ZRElementEvent } from '../../util/types';
+import BarSeriesModel, { BarSeriesOption, BarDataItemOption } from './BarSeries';
+import type Axis2D from '../../coord/cartesian/Axis2D';
+import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
+import type { RectLike } from 'zrender/src/core/BoundingRect';
+import type Model from '../../model/Model';
+
+const BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'borderWidth'] as const;
+const _eventPos = [0, 0];
+
+const mathMax = Math.max;
+const mathMin = Math.min;
+
+type CoordSysOfBar = BarSeriesModel['coordinateSystem'];
+type RectShape = graphic.Rect['shape']
+type SectorShape = graphic.Sector['shape']
+
+type SectorLayout = SectorShape;
+type RectLayout = RectShape;
+
+function isCartesian2D(coord: CoordSysOfBar): coord is Cartesian2D {
+    return coord.type === 'cartesian2d';
+}
 
-var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'barBorderWidth'];
-var _eventPos = [0, 0];
-
-// FIXME
-// Just for compatible with ec2.
-zrUtil.extend(Model.prototype, barItemStyle);
-
-function getClipArea(coord, data) {
-    var coordSysClipArea = coord.getArea && coord.getArea();
-    if (coord.type === 'cartesian2d') {
+function getClipArea(coord: CoordSysOfBar, data: List) {
+    if (isCartesian2D(coord)) {
+        var coordSysClipArea = coord.getArea && coord.getArea();
         var baseAxis = coord.getBaseAxis();
         // When boundaryGap is false or using time axis. bar may exceed the grid.
         // We should not clip this part.
@@ -62,11 +78,20 @@ function getClipArea(coord, data) {
     return coordSysClipArea;
 }
 
-export default echarts.extendChartView({
 
-    type: 'bar',
+class BarView extends ChartView {
+    static type = 'bar' as const
+    type = BarView.type
+
+    _data: List
+
+    _isLargeDraw: boolean
+
+    _backgroundGroup: graphic.Group
+
+    _backgroundEls: (graphic.Rect | graphic.Sector)[]
 
-    render: function (seriesModel, ecModel, api) {
+    render(seriesModel: BarSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
         this._updateDrawMode(seriesModel);
 
         var coordinateSystemType = seriesModel.get('coordinateSystem');
@@ -83,37 +108,38 @@ export default echarts.extendChartView({
         }
 
         return this.group;
-    },
+    }
 
-    incrementalPrepareRender: function (seriesModel, ecModel, api) {
+    incrementalPrepareRender(seriesModel: BarSeriesModel) {
         this._clear();
         this._updateDrawMode(seriesModel);
-    },
+    }
 
-    incrementalRender: function (params, seriesModel, ecModel, api) {
+    incrementalRender(
+        params: StageHandlerProgressParams, seriesModel: BarSeriesModel) {
         // Do not support progressive in normal mode.
         this._incrementalRenderLarge(params, seriesModel);
-    },
+    }
 
-    _updateDrawMode: function (seriesModel) {
+    _updateDrawMode(seriesModel: BarSeriesModel) {
         var isLargeDraw = seriesModel.pipelineContext.large;
-        if (this._isLargeDraw == null || isLargeDraw ^ this._isLargeDraw) {
+        if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) {
             this._isLargeDraw = isLargeDraw;
             this._clear();
         }
-    },
+    }
 
-    _renderNormal: function (seriesModel, ecModel, api) {
+    _renderNormal(seriesModel: BarSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
         var group = this.group;
         var data = seriesModel.getData();
         var oldData = this._data;
 
         var coord = seriesModel.coordinateSystem;
         var baseAxis = coord.getBaseAxis();
-        var isHorizontalOrRadial;
+        var isHorizontalOrRadial: boolean;
 
         if (coord.type === 'cartesian2d') {
-            isHorizontalOrRadial = baseAxis.isHorizontal();
+            isHorizontalOrRadial = (baseAxis as Axis2D).isHorizontal();
         }
         else if (coord.type === 'polar') {
             isHorizontalOrRadial = baseAxis.dim === 'angle';
@@ -133,8 +159,8 @@ export default echarts.extendChartView({
         var drawBackground = seriesModel.get('showBackground', true);
         var backgroundModel = seriesModel.getModel('backgroundStyle');
 
-        var bgEls = [];
-        var oldBgEls = this._backgroundEls || [];
+        var bgEls: BarView['_backgroundEls'] = [];
+        var oldBgEls = this._backgroundEls;
 
         data.diff(oldData)
             .add(function (dataIndex) {
@@ -142,8 +168,10 @@ export default echarts.extendChartView({
                 var layout = getLayout[coord.type](data, dataIndex, itemModel);
 
                 if (drawBackground) {
-                    var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, layout);
-                    bgEl.useStyle(backgroundModel.getBarItemStyle());
+                    var bgEl = createBackgroundEl(
+                        coord, isHorizontalOrRadial, layout
+                    );
+                    bgEl.useStyle(getBarItemStyle(backgroundModel));
                     bgEls[dataIndex] = bgEl;
                 }
 
@@ -178,14 +206,16 @@ export default echarts.extendChartView({
 
                 if (drawBackground) {
                     var bgEl = oldBgEls[oldIndex];
-                    bgEl.useStyle(backgroundModel.getBarItemStyle());
+                    bgEl.useStyle(getBarItemStyle(backgroundModel));
                     bgEls[newIndex] = bgEl;
 
                     var shape = createBackgroundShape(isHorizontalOrRadial, layout, coord);
-                    graphic.updateProps(bgEl, { shape: shape }, animationModel, newIndex);
+                    graphic.updateProps(
+                        bgEl as graphic.Path, { shape: shape }, animationModel, newIndex
+                    );
                 }
 
-                var el = oldData.getItemGraphicEl(oldIndex);
+                var el = oldData.getItemGraphicEl(oldIndex) as graphic.Rect | graphic.Sector;
                 if (!data.hasValue(newIndex)) {
                     group.remove(el);
                     return;
@@ -200,7 +230,9 @@ export default echarts.extendChartView({
                 }
 
                 if (el) {
-                    graphic.updateProps(el, {shape: layout}, animationModel, newIndex);
+                    graphic.updateProps(el as graphic.Path, {
+                        shape: layout
+                    }, animationModel, newIndex);
                 }
                 else {
                     el = elementCreator[coord.type](
@@ -220,10 +252,10 @@ export default echarts.extendChartView({
             .remove(function (dataIndex) {
                 var el = oldData.getItemGraphicEl(dataIndex);
                 if (coord.type === 'cartesian2d') {
-                    el && removeRect(dataIndex, animationModel, el);
+                    el && removeRect(dataIndex, animationModel, el as graphic.Rect);
                 }
                 else {
-                    el && removeSector(dataIndex, animationModel, el);
+                    el && removeSector(dataIndex, animationModel, el as graphic.Sector);
                 }
             })
             .execute();
@@ -238,9 +270,9 @@ export default echarts.extendChartView({
         this._backgroundEls = bgEls;
 
         this._data = data;
-    },
+    }
 
-    _renderLarge: function (seriesModel, ecModel, api) {
+    _renderLarge(seriesModel: BarSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
         this._clear();
         createLarge(seriesModel, this.group);
 
@@ -254,32 +286,30 @@ export default echarts.extendChartView({
         else {
             this.group.removeClipPath();
         }
-    },
+    }
 
-    _incrementalRenderLarge: function (params, seriesModel) {
+    _incrementalRenderLarge(params: StageHandlerProgressParams, seriesModel: BarSeriesModel) {
         this._removeBackground();
         createLarge(seriesModel, this.group, true);
-    },
-
-    dispose: zrUtil.noop,
+    }
 
-    remove: function (ecModel) {
+    remove(ecModel?: GlobalModel) {
         this._clear(ecModel);
-    },
+    }
 
-    _clear: function (ecModel) {
+    _clear(ecModel?: GlobalModel) {
         var group = this.group;
         var data = this._data;
         if (ecModel && ecModel.get('animation') && data && !this._isLargeDraw) {
             this._removeBackground();
             this._backgroundEls = [];
 
-            data.eachItemGraphicEl(function (el) {
+            data.eachItemGraphicEl(function (el: ECElement & (graphic.Sector | graphic.Rect)) {
                 if (el.type === 'sector') {
-                    removeSector(el.dataIndex, ecModel, el);
+                    removeSector(el.dataIndex, ecModel, el as (graphic.Sector));
                 }
                 else {
-                    removeRect(el.dataIndex, ecModel, el);
+                    removeRect(el.dataIndex, ecModel, el as (graphic.Rect));
                 }
             });
         }
@@ -287,20 +317,21 @@ export default echarts.extendChartView({
             group.removeAll();
         }
         this._data = null;
-    },
+    }
 
-    _removeBackground: function () {
+    _removeBackground() {
         this.group.remove(this._backgroundGroup);
         this._backgroundGroup = null;
     }
+}
 
-});
-
-var mathMax = Math.max;
-var mathMin = Math.min;
-
-var clip = {
-    cartesian2d: function (coordSysBoundingRect, layout) {
+interface Clipper {
+    (coordSysBoundingRect: RectLike, layout: RectLayout | SectorLayout): boolean
+}
+var clip: {
+    [key in 'cartesian2d' | 'polar']: Clipper
+} = {
+    cartesian2d(coordSysBoundingRect: RectLike, layout: graphic.Rect['shape']) {
         var signWidth = layout.width < 0 ? -1 : 1;
         var signHeight = layout.height < 0 ? -1 : 1;
         // Needs positive width and height
@@ -338,15 +369,24 @@ var clip = {
         return clipped;
     },
 
-    polar: function (coordSysClipArea) {
+    polar() {
         return false;
     }
 };
 
-var elementCreator = {
+interface ElementCreator {
+    (
+        dataIndex: number, layout: RectLayout | SectorLayout, isHorizontalOrRadial: boolean,
+        animationModel: BarSeriesModel, isUpdate: boolean, roundCap?: boolean
+    ): graphic.Sector | graphic.Rect
+}
+
+var elementCreator: {
+    [key in 'polar' | 'cartesian2d']: ElementCreator
+} = {
 
-    cartesian2d: function (
-        dataIndex, layout, isHorizontal,
+    cartesian2d(
+        dataIndex, layout: RectLayout, isHorizontal,
         animationModel, isUpdate
     ) {
         var rect = new graphic.Rect({
@@ -359,8 +399,8 @@ var elementCreator = {
         // Animation
         if (animationModel) {
             var rectShape = rect.shape;
-            var animateProperty = isHorizontal ? 'height' : 'width';
-            var animateTarget = {};
+            var animateProperty = isHorizontal ? 'height' : 'width' as 'width' | 'height';
+            var animateTarget = {} as RectShape;
             rectShape[animateProperty] = 0;
             animateTarget[animateProperty] = layout[animateProperty];
             graphic[isUpdate ? 'updateProps' : 'initProps'](rect, {
@@ -371,8 +411,8 @@ var elementCreator = {
         return rect;
     },
 
-    polar: function (
-        dataIndex, layout, isRadial,
+    polar(
+        dataIndex: number, layout: SectorLayout, isRadial: boolean,
         animationModel, isUpdate, roundCap
     ) {
         // Keep the same logic with bar in catesion: use end value to control
@@ -393,8 +433,8 @@ var elementCreator = {
         // Animation
         if (animationModel) {
             var sectorShape = sector.shape;
-            var animateProperty = isRadial ? 'r' : 'endAngle';
-            var animateTarget = {};
+            var animateProperty = isRadial ? 'r' : 'endAngle' as 'r' | 'endAngle';
+            var animateTarget = {} as SectorShape;
             sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
             animateTarget[animateProperty] = layout[animateProperty];
             graphic[isUpdate ? 'updateProps' : 'initProps'](sector, {
@@ -406,7 +446,11 @@ var elementCreator = {
     }
 };
 
-function removeRect(dataIndex, animationModel, el) {
+function removeRect(
+    dataIndex: number,
+    animationModel: BarSeriesModel | GlobalModel,
+    el: graphic.Rect
+) {
     // Not show text when animating
     el.style.text = null;
     graphic.updateProps(el, {
@@ -418,7 +462,11 @@ function removeRect(dataIndex, animationModel, el) {
     });
 }
 
-function removeSector(dataIndex, animationModel, el) {
+function removeSector(
+    dataIndex: number,
+    animationModel: BarSeriesModel | GlobalModel,
+    el: graphic.Sector
+) {
     // Not show text when animating
     el.style.text = null;
     graphic.updateProps(el, {
@@ -430,9 +478,14 @@ function removeSector(dataIndex, animationModel, el) {
     });
 }
 
-var getLayout = {
-    cartesian2d: function (data, dataIndex, itemModel) {
-        var layout = data.getItemLayout(dataIndex);
+interface GetLayout {
+    (data: List, dataIndex: number, itemModel: Model<BarDataItemOption>): RectLayout | SectorLayout
+}
+var getLayout: {
+    [key in 'cartesian2d' | 'polar']: GetLayout
+} = {
+    cartesian2d(data, dataIndex, itemModel): RectLayout {
+        var layout = data.getItemLayout(dataIndex) as RectLayout;
         var fixedLineWidth = getLineWidth(itemModel, layout);
 
         // fix layout with lineWidth
@@ -446,7 +499,7 @@ var getLayout = {
         };
     },
 
-    polar: function (data, dataIndex, itemModel) {
+    polar(data, dataIndex, itemModel): SectorLayout {
         var layout = data.getItemLayout(dataIndex);
         return {
             cx: layout.cx,
@@ -455,24 +508,30 @@ var getLayout = {
             r: layout.r,
             startAngle: layout.startAngle,
             endAngle: layout.endAngle
-        };
+        } as SectorLayout;
     }
 };
 
-function isZeroOnPolar(layout) {
+function isZeroOnPolar(layout: SectorLayout) {
     return layout.startAngle != null
         && layout.endAngle != null
         && layout.startAngle === layout.endAngle;
 }
 
 function updateStyle(
-    el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar
+    el: graphic.Sector | graphic.Rect,
+    data: List, dataIndex: number,
+    itemModel: Model<BarDataItemOption>,
+    layout: RectLayout | SectorLayout,
+    seriesModel: BarSeriesModel,
+    isHorizontal: boolean,
+    isPolar: boolean
 ) {
     var color = data.getItemVisual(dataIndex, 'color');
     var opacity = data.getItemVisual(dataIndex, 'opacity');
     var stroke = data.getVisual('borderColor');
     var itemStyleModel = itemModel.getModel('itemStyle');
-    var hoverStyle = itemModel.getModel('emphasis.itemStyle').getBarItemStyle();
+    var hoverStyle = getBarItemStyle(itemModel.getModel(['emphasis', 'itemStyle']));
 
     if (!isPolar) {
         el.setShape('r', itemStyleModel.get('barBorderRadius') || 0);
@@ -480,34 +539,37 @@ function updateStyle(
 
     el.useStyle(zrUtil.defaults(
         {
-            stroke: isZeroOnPolar(layout) ? 'none' : stroke,
-            fill: isZeroOnPolar(layout) ? 'none' : color,
+            stroke: isZeroOnPolar(layout as SectorLayout) ? 'none' : stroke,
+            fill: isZeroOnPolar(layout as SectorLayout) ? 'none' : color,
             opacity: opacity
         },
-        itemStyleModel.getBarItemStyle()
+        getBarItemStyle(itemStyleModel)
     ));
 
     var cursorStyle = itemModel.getShallow('cursor');
     cursorStyle && el.attr('cursor', cursorStyle);
 
-    var labelPositionOutside = isHorizontal
-        ? (layout.height > 0 ? 'bottom' : 'top')
-        : (layout.width > 0 ? 'left' : 'right');
-
     if (!isPolar) {
+        var labelPositionOutside = isHorizontal
+            ? ((layout as RectLayout).height > 0 ? 'bottom' : 'top')
+            : ((layout as RectLayout).width > 0 ? 'left' : 'right');
+
         setLabel(
             el.style, hoverStyle, itemModel, color,
             seriesModel, dataIndex, labelPositionOutside
         );
     }
-    if (isZeroOnPolar(layout)) {
+    if (isZeroOnPolar(layout as SectorLayout)) {
         hoverStyle.fill = hoverStyle.stroke = 'none';
     }
     graphic.setHoverStyle(el, hoverStyle);
 }
 
 // In case width or height are too small.
-function getLineWidth(itemModel, rawLayout) {
+function getLineWidth(
+    itemModel: Model<BarSeriesOption>,
+    rawLayout: RectLayout
+) {
     var lineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0;
     // width or height may be NaN for empty data
     var width = isNaN(rawLayout.width) ? Number.MAX_VALUE : Math.abs(rawLayout.width);
@@ -515,19 +577,32 @@ function getLineWidth(itemModel, rawLayout) {
     return Math.min(lineWidth, width, height);
 }
 
+class LagePathShape {
+    points: ArrayLike<number>
+}
+interface LargePathProps extends PathProps {
+    shape?: LagePathShape
+}
+class LargePath extends Path {
+    type = 'largeBar'
 
-var LargePath = Path.extend({
+    shape: LagePathShape
 
-    type: 'largeBar',
+    __startPoint: number[]
+    __baseDimIdx: number
+    __largeDataIndices: ArrayLike<number>
+    __barWidth: number
 
-    shape: {points: []},
+    constructor(opts?: LargePathProps) {
+        super(opts, null, new LagePathShape());
+    }
 
-    buildPath: function (ctx, shape) {
+    buildPath(ctx: CanvasRenderingContext2D, shape: LagePathShape) {
         // Drawing lines is more efficient than drawing
         // a whole line or drawing rects.
-        var points = shape.points;
-        var startPoint = this.__startPoint;
-        var baseDimIdx = this.__baseDimIdx;
+        const points = shape.points;
+        const startPoint = this.__startPoint;
+        const baseDimIdx = this.__baseDimIdx;
 
         for (var i = 0; i < points.length; i += 2) {
             startPoint[baseDimIdx] = points[i + baseDimIdx];
@@ -535,9 +610,13 @@ var LargePath = Path.extend({
             ctx.lineTo(points[i], points[i + 1]);
         }
     }
-});
+}
 
-function createLarge(seriesModel, group, incremental) {
+function createLarge(
+    seriesModel: BarSeriesModel,
+    group: Group,
+    incremental?: boolean
+) {
     // TODO support polar
     var data = seriesModel.getData();
     var startPoint = [];
@@ -551,37 +630,37 @@ function createLarge(seriesModel, group, incremental) {
     var drawBackground = seriesModel.get('showBackground', true);
 
     if (drawBackground) {
-        var points = data.getLayout('largeBackgroundPoints');
-        var backgroundStartPoint = [];
+        const points = data.getLayout('largeBackgroundPoints');
+        const backgroundStartPoint: number[] = [];
         backgroundStartPoint[1 - baseDimIdx] = data.getLayout('backgroundStart');
 
-        var bgEl = new LargePath({
+        const bgEl = new LargePath({
             shape: {points: points},
             incremental: !!incremental,
-            __startPoint: backgroundStartPoint,
-            __baseDimIdx: baseDimIdx,
-            __largeDataIndices: largeDataIndices,
-            __barWidth: barWidth,
             silent: true,
             z2: 0
         });
+        bgEl.__startPoint = backgroundStartPoint;
+        bgEl.__baseDimIdx = baseDimIdx;
+        bgEl.__largeDataIndices = largeDataIndices;
+        bgEl.__barWidth = barWidth;
         setLargeBackgroundStyle(bgEl, backgroundModel, data);
         group.add(bgEl);
     }
 
     var el = new LargePath({
         shape: {points: data.getLayout('largePoints')},
-        incremental: !!incremental,
-        __startPoint: startPoint,
-        __baseDimIdx: baseDimIdx,
-        __largeDataIndices: largeDataIndices,
-        __barWidth: barWidth
+        incremental: !!incremental
     });
+    el.__startPoint = startPoint;
+    el.__baseDimIdx = baseDimIdx;
+    el.__largeDataIndices = largeDataIndices;
+    el.__barWidth = barWidth;
     group.add(el);
     setLargeStyle(el, seriesModel, data);
 
     // Enable tooltip and user mouse/touch event handlers.
-    el.seriesIndex = seriesModel.seriesIndex;
+    (el as ECElement).seriesIndex = seriesModel.seriesIndex;
 
     if (!seriesModel.get('silent')) {
         el.on('mousedown', largePathUpdateDataIndex);
@@ -590,13 +669,13 @@ function createLarge(seriesModel, group, incremental) {
 }
 
 // Use throttle to avoid frequently traverse to find dataIndex.
-var largePathUpdateDataIndex = throttle(function (event) {
+var largePathUpdateDataIndex = throttle(function (this: LargePath, event: ZRElementEvent) {
     var largePath = this;
     var dataIndex = largePathFindDataIndex(largePath, event.offsetX, event.offsetY);
-    largePath.dataIndex = dataIndex >= 0 ? dataIndex : null;
+    (largePath as ECElement).dataIndex = dataIndex >= 0 ? dataIndex : null;
 }, 30, false);
 
-function largePathFindDataIndex(largePath, x, y) {
+function largePathFindDataIndex(largePath: LargePath, x: number, y: number) {
     var baseDimIdx = largePath.__baseDimIdx;
     var valueDimIdx = 1 - baseDimIdx;
     var points = largePath.shape.points;
@@ -630,7 +709,11 @@ function largePathFindDataIndex(largePath, x, y) {
     return -1;
 }
 
-function setLargeStyle(el, seriesModel, data) {
+function setLargeStyle(
+    el: LargePath,
+    seriesModel: BarSeriesModel,
+    data: List
+) {
     var borderColor = data.getVisual('borderColor') || data.getVisual('color');
     var itemStyle = seriesModel.getModel('itemStyle').getItemStyle(['color', 'borderColor']);
 
@@ -640,51 +723,62 @@ function setLargeStyle(el, seriesModel, data) {
     el.style.lineWidth = data.getLayout('barWidth');
 }
 
-function setLargeBackgroundStyle(el, backgroundModel, data) {
+function setLargeBackgroundStyle(
+    el: LargePath,
+    backgroundModel: Model<BarSeriesOption['backgroundStyle']>,
+    data: List
+) {
     var borderColor = backgroundModel.get('borderColor') || backgroundModel.get('color');
     var itemStyle = backgroundModel.getItemStyle(['color', 'borderColor']);
 
     el.useStyle(itemStyle);
     el.style.fill = null;
     el.style.stroke = borderColor;
-    el.style.lineWidth = data.getLayout('barWidth');
+    el.style.lineWidth = data.getLayout('barWidth') as number;
 }
 
-function createBackgroundShape(isHorizontalOrRadial, layout, coord) {
-    var coordLayout;
-    var isPolar = coord.type === 'polar';
-    if (isPolar) {
-        coordLayout = coord.getArea();
+function createBackgroundShape(
+    isHorizontalOrRadial: boolean,
+    layout: SectorLayout | RectLayout,
+    coord: CoordSysOfBar
+): SectorShape | RectShape {
+    if (isCartesian2D(coord)) {
+        const rectShape = layout as RectShape;
+        const coordLayout = coord.getArea();
+        return {
+            x: isHorizontalOrRadial ? rectShape.x : coordLayout.x,
+            y: isHorizontalOrRadial ? coordLayout.y : rectShape.y,
+            width: isHorizontalOrRadial ? rectShape.width : coordLayout.width,
+            height: isHorizontalOrRadial ? coordLayout.height : rectShape.height
+        } as RectShape;
     }
     else {
-        coordLayout = coord.grid.getRect();
-    }
-
-    if (isPolar) {
+        const coordLayout = coord.getArea();
+        const sectorShape = layout as SectorShape;
         return {
             cx: coordLayout.cx,
             cy: coordLayout.cy,
-            r0: isHorizontalOrRadial ? coordLayout.r0 : layout.r0,
-            r: isHorizontalOrRadial ? coordLayout.r : layout.r,
-            startAngle: isHorizontalOrRadial ? layout.startAngle : 0,
-            endAngle: isHorizontalOrRadial ? layout.endAngle : Math.PI * 2
-        };
-    }
-    else {
-        return {
-            x: isHorizontalOrRadial ? layout.x : coordLayout.x,
-            y: isHorizontalOrRadial ? coordLayout.y : layout.y,
-            width: isHorizontalOrRadial ? layout.width : coordLayout.width,
-            height: isHorizontalOrRadial ? coordLayout.height : layout.height
-        };
+            r0: isHorizontalOrRadial ? coordLayout.r0 : sectorShape.r0,
+            r: isHorizontalOrRadial ? coordLayout.r : sectorShape.r,
+            startAngle: isHorizontalOrRadial ? sectorShape.startAngle : 0,
+            endAngle: isHorizontalOrRadial ? sectorShape.endAngle : Math.PI * 2
+        } as SectorShape;
     }
 }
 
-function createBackgroundEl(coord, isHorizontalOrRadial, layout) {
+function createBackgroundEl(
+    coord: CoordSysOfBar,
+    isHorizontalOrRadial: boolean,
+    layout: SectorLayout | RectLayout
+): graphic.Rect | graphic.Sector {
     var ElementClz = coord.type === 'polar' ? graphic.Sector : graphic.Rect;
     return new ElementClz({
-        shape: createBackgroundShape(isHorizontalOrRadial, layout, coord),
+        shape: createBackgroundShape(isHorizontalOrRadial, layout, coord) as any,
         silent: true,
         z2: 0
     });
 }
+
+ChartView.registerClass(BarView);
+
+export default BarView;
\ No newline at end of file
diff --git a/src/chart/bar/BaseBarSeries.ts b/src/chart/bar/BaseBarSeries.ts
index 9a2ce37..d8c5dc7 100644
--- a/src/chart/bar/BaseBarSeries.ts
+++ b/src/chart/bar/BaseBarSeries.ts
@@ -17,20 +17,76 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import SeriesModel from '../../model/Series';
 import createListFromArray from '../helper/createListFromArray';
+import {
+    SeriesOption,
+    SeriesOnCartesianOptionMixin,
+    SeriesOnPolarOptionMixin,
+    LabelOption,
+    ItemStyleOption,
+    ScaleDataValue
+} from '../../util/types';
+import GlobalModel from '../../model/Global';
+import Cartesian2D from '../../coord/cartesian/Cartesian2D';
+
+
+export interface BaseBarSeriesOption extends SeriesOption, SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin {
+
+    /**
+     * Min height of bar
+     */
+    barMinHeight?: number
+    /**
+     * Min angle of bar. Avaiable on polar coordinate system
+     */
+    barMinAngle?: number
+
+    /**
+     * Max width of bar. Default to be 1 on cartesian coordinate system. Otherwise it's null
+     */
+    barMaxWidth?: number
 
-export default SeriesModel.extend({
+    barMinWidth?: number
 
-    type: 'series.__base_bar__',
+    /**
+     * Bar width. Will be calculated automatically.
+     * Can be pixel width or percent string.
+     */
+    barWidth?: number | string
+
+    /**
+     * Gap between each bar inside category. Default to be 30%. Can be an aboslute pixel value
+     */
+    barGap?: string | number
+
+    /**
+     * Gap between each category. Default to be 20%. can be an absolute pixel value.
+     */
+    barCategoryGap?: string | number
+
+    large?: boolean
+    largeThreshold?: number
+
+    label?: LabelOption
+    itemStyle?: ItemStyleOption
+    emphasis?: {
+        label?: LabelOption
+        itemStyle?: ItemStyleOption
+    }
+}
 
-    getInitialData: function (option, ecModel) {
+class BaseBarSeriesModel<Opts extends BaseBarSeriesOption = BaseBarSeriesOption> extends SeriesModel<Opts> {
+
+    static type = 'series.__base_bar__'
+    type = BaseBarSeriesModel.type
+
+
+    getInitialData(option: Opts, ecModel: GlobalModel) {
         return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
-    },
+    }
 
-    getMarkerPosition: function (value) {
+    getMarkerPosition(value: ScaleDataValue[]) {
         var coordSys = this.coordinateSystem;
         if (coordSys) {
             // PENDING if clamp ?
@@ -38,16 +94,16 @@ export default SeriesModel.extend({
             var data = this.getData();
             var offset = data.getLayout('offset');
             var size = data.getLayout('size');
-            var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;
+            var offsetIndex = (coordSys as Cartesian2D).getBaseAxis().isHorizontal() ? 0 : 1;
             pt[offsetIndex] += offset + size / 2;
             return pt;
         }
         return [NaN, NaN];
-    },
+    }
 
-    defaultOption: {
-        zlevel: 0,                  // 一级层叠
-        z: 2,                       // 二级层叠
+    static defaultOption: BaseBarSeriesOption = {
+        zlevel: 0,
+        z: 2,
         coordinateSystem: 'cartesian2d',
         legendHoverLink: true,
         // stack: null
@@ -56,9 +112,7 @@ export default SeriesModel.extend({
         // xAxisIndex: 0,
         // yAxisIndex: 0,
 
-        // 最小高度改为0
         barMinHeight: 0,
-        // 最小角度为0,仅对极坐标系下的柱状图有效
         barMinAngle: 0,
         // cursor: null,
 
@@ -67,21 +121,11 @@ export default SeriesModel.extend({
         progressive: 3e3,
         progressiveChunkMode: 'mod',
 
-        // barMaxWidth: null,
-
-        // In cartesian, the default value is 1. Otherwise null.
-        // barMinWidth: null,
-
-        // 默认自适应
-        // barWidth: null,
-        // 柱间距离,默认为柱形宽度的30%,可设固定值
-        // barGap: '30%',
-        // 类目间柱形距离,默认为类目间距的20%,可设固定值
-        // barCategoryGap: '20%',
-        // label: {
-        //      show: false
-        // },
         itemStyle: {},
         emphasis: {}
     }
-});
\ No newline at end of file
+}
+
+SeriesModel.registerClass(BaseBarSeriesModel);
+
+export default BaseBarSeriesModel;
\ No newline at end of file
diff --git a/src/chart/bar/PictorialBarSeries.ts b/src/chart/bar/PictorialBarSeries.ts
index 61ff4cd..fb41cb0 100644
--- a/src/chart/bar/PictorialBarSeries.ts
+++ b/src/chart/bar/PictorialBarSeries.ts
@@ -17,29 +17,114 @@
 * under the License.
 */
 
-// @ts-nocheck
+import BaseBarSeriesModel, { BaseBarSeriesOption } from './BaseBarSeries';
+import SeriesModel from '../../model/Series';
+import { OptionDataValue, ItemStyleOption, LabelOption, AnimationOptionMixin } from '../../util/types';
+import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
 
-import BaseBarSeries from './BaseBarSeries';
+interface PictorialBarSeriesSymbolOption {
+    /**
+     * Customized bar shape
+     */
+    symbol?: string
+    /**
+     * Can be ['100%', '100%'], null means auto.
+     * The percent will be relative to category width. If no repeat.
+     * Will be relative to symbolBoundingData.
+     */
+    symbolSize?: (number | string)[] | number | string
 
-var PictorialBarSeries = BaseBarSeries.extend({
+    symbolRotate?: number
 
-    type: 'series.pictorialBar',
+    /**
+     * Default to be auto
+     */
+    symbolPosition?: 'start' | 'end' | 'center'
 
-    dependencies: ['grid'],
+    /**
+     * Can be percent offset relative to the symbolSize
+     */
+    symbolOffset?: (number | string)[] | number | string
+    /**
+     * start margin and end margin. Can be a number or a percent string relative to symbolSize.
+     * Auto margin by default.
+     */
+    symbolMargin?: (number | string)[] | number | string
+
+    /**
+     * true: means auto calculate repeat times and cut by data.
+     * a number: specifies repeat times, and do not cut by data.
+     * 'fixed': means auto calculate repeat times but do not cut by data.
+     *
+     * Otherwise means no repeat
+     */
+    symbolRepeat?: boolean | number | 'fixed'
+
+    /**
+     * From start to end or end to start.
+     */
+    symbolRepeatDirection?: 'start' | 'end'
+
+    symbolClip?: boolean
+
+    /**
+     * It will define the size of graphic elements.
+     */
+    symbolBoundingData?: number | number[]
+
+    symbolPatternSize?: number
+}
+
+type PictorialBarValue = OptionDataValue
+
+export interface PictorialBarDataItemOption extends PictorialBarSeriesSymbolOption,
+    // Pictorial bar support configure animation in each data item.
+    AnimationOptionMixin {
+    name?: string
+
+    value?: PictorialBarValue
+
+    itemStyle?: ItemStyleOption
+    label?: LabelOption
+
+    emphasis?: {
+        itemStyle?: ItemStyleOption
+        label?: LabelOption
+    }
+
+    hoverAnimation?: boolean
+
+    z?: number
+
+    cursor?: string
+}
+
+export interface PictorialBarSeriesOption extends BaseBarSeriesOption, PictorialBarSeriesSymbolOption {
+    coordinateSystem?: 'cartesian2d'
+
+    data?: (PictorialBarDataItemOption | PictorialBarValue)[]
+
+    hoverAnimation?: boolean
+}
+
+class PictorialBarSeriesModel extends BaseBarSeriesModel<PictorialBarSeriesOption> {
+    static type = 'series.pictorialBar'
+    type = PictorialBarSeriesModel.type
+
+    static dependencies = ['grid']
+
+    coordinateSystem: Cartesian2D
+
+    static defaultOption: PictorialBarSeriesOption = {
 
-    defaultOption: {
         symbol: 'circle',     // Customized bar shape
-        symbolSize: null,     // Can be ['100%', '100%'], null means auto.
+        symbolSize: null,     //
         symbolRotate: null,
 
         symbolPosition: null, // 'start' or 'end' or 'center', null means auto.
         symbolOffset: null,
-        symbolMargin: null,   // start margin and end margin. Can be a number or a percent string.
-                                // Auto margin by defualt.
-        symbolRepeat: false,  // false/null/undefined, means no repeat.
-                                // Can be true, means auto calculate repeat times and cut by data.
-                                // Can be a number, specifies repeat times, and do not cut by data.
-                                // Can be 'fixed', means auto calculate repeat times but do not cut by data.
+        symbolMargin: null,
+        symbolRepeat: false,
         symbolRepeatDirection: 'end', // 'end' means from 'start' to 'end'.
 
         symbolClip: false,
@@ -53,13 +138,15 @@ var PictorialBarSeries = BaseBarSeries.extend({
         // Disable progressive
         progressive: 0,
         hoverAnimation: false // Open only when needed.
-    },
+    }
 
-    getInitialData: function (option) {
+    getInitialData(option: PictorialBarSeriesOption) {
         // Disable stack.
-        option.stack = null;
-        return PictorialBarSeries.superApply(this, 'getInitialData', arguments);
+        (option as any).stack = null;
+        return super.getInitialData.apply(this, arguments as any);
     }
-});
+}
+
+SeriesModel.registerClass(PictorialBarSeriesModel);
 
-export default PictorialBarSeries;
\ No newline at end of file
+export default PictorialBarSeriesModel;
\ No newline at end of file
diff --git a/src/chart/bar/PictorialBarView.ts b/src/chart/bar/PictorialBarView.ts
index 080d939..71f695f 100644
--- a/src/chart/bar/PictorialBarView.ts
+++ b/src/chart/bar/PictorialBarView.ts
@@ -17,41 +17,132 @@
 * 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 {createSymbol} from '../../util/symbol';
 import {parsePercent, isNumeric} from '../../util/number';
 import {setLabel} from './helper';
-
-
-var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'borderWidth'];
+import ChartView from '../../view/Chart';
+import ComponentView from '../../view/Component';
+import PictorialBarSeriesModel, {PictorialBarDataItemOption} from './PictorialBarSeries';
+import ExtensionAPI from '../../ExtensionAPI';
+import List from '../../data/List';
+import GlobalModel from '../../model/Global';
+import Model from '../../model/Model';
+import { ColorString, ECElement, AnimationOptionMixin } from '../../util/types';
+import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
+import type Displayable from 'zrender/src/graphic/Displayable';
+import type Axis2D from '../../coord/cartesian/Axis2D';
+import type Element from 'zrender/src/Element';
+
+
+var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'borderWidth'] as const;
 
 // index: +isHorizontal
 var LAYOUT_ATTRS = [
     {xy: 'x', wh: 'width', index: 0, posDesc: ['left', 'right']},
     {xy: 'y', wh: 'height', index: 1, posDesc: ['top', 'bottom']}
-];
+] as const;
 
 var pathForLineWidth = new graphic.Circle();
 
-var BarView = echarts.extendChartView({
+type ItemModel = Model<PictorialBarDataItemOption> & {
+    getAnimationDelayParams(path: any): {index: number, count: number}
+    isAnimationEnabled(): boolean
+}
+type RectShape = graphic.Rect['shape']
+type RectLayout = RectShape
+
+type PictorialSymbol = ReturnType<typeof createSymbol> & {
+    __pictorialAnimationIndex: number
+    __pictorialRepeatTimes: number
+}
+
+interface SymbolMeta {
+    dataIndex: number
+
+    symbolPatternSize: number
+    symbolType: string
+    symbolMargin: number
+    symbolSize: number[]
+    symbolScale: number[]
+    symbolRepeat: PictorialBarDataItemOption['symbolRepeat']
+    symbolClip: PictorialBarDataItemOption['symbolClip']
+    symbolRepeatDirection: PictorialBarDataItemOption['symbolRepeatDirection']
+
+    layout: RectLayout
+
+    repeatTimes: number
+
+    rotation: number
+
+    pathPosition: number[]
+    bundlePosition: number[]
+
+    pxSign: number
+
+    barRectShape: RectShape
+    clipShape: RectShape
+
+    boundingLength: number
+    repeatCutLength: number
+
+    valueLineWidth: number
+
+    opacity: number
+    color: ColorString
+    z2: number
+
+    itemModel: ItemModel
+
+    animationModel?: ItemModel
+
+    hoverAnimation: boolean
+}
+
+interface CreateOpts {
+    ecSize: { width: number, height: number }
+    seriesModel: PictorialBarSeriesModel
+    coordSys: Cartesian2D
+    coordSysExtent: number[][]
+    isHorizontal: boolean
+    valueDim: typeof LAYOUT_ATTRS[number]
+    categoryDim: typeof LAYOUT_ATTRS[number]
+}
+
+interface PictorialBarElement extends graphic.Group {
+    __pictorialBundle: graphic.Group
+    __pictorialShapeStr: string
+    __pictorialSymbolMeta: SymbolMeta
+
+    __pictorialMainPath: PictorialSymbol
 
-    type: 'pictorialBar',
+    __pictorialBarRect: graphic.Rect
 
-    render: function (seriesModel, ecModel, api) {
+    __pictorialClipPath: graphic.Rect
+}
+
+class PictorialBarView extends ChartView {
+    static type = 'pictorialBar'
+    readonly type = PictorialBarView.type
+
+    private _data: List
+
+    render(
+        seriesModel: PictorialBarSeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI
+    ) {
         var group = this.group;
         var data = seriesModel.getData();
         var oldData = this._data;
 
         var cartesian = seriesModel.coordinateSystem;
         var baseAxis = cartesian.getBaseAxis();
-        var isHorizontal = !!baseAxis.isHorizontal();
+        var isHorizontal = baseAxis.isHorizontal();
         var coordSysRect = cartesian.grid.getRect();
 
-        var opt = {
+        var opt: CreateOpts = {
             ecSize: {width: api.getWidth(), height: api.getHeight()},
             seriesModel: seriesModel,
             coordSys: cartesian,
@@ -61,7 +152,7 @@ var BarView = echarts.extendChartView({
             ],
             isHorizontal: isHorizontal,
             valueDim: LAYOUT_ATTRS[+isHorizontal],
-            categoryDim: LAYOUT_ATTRS[1 - isHorizontal]
+            categoryDim: LAYOUT_ATTRS[1 - (+isHorizontal)]
         };
 
         data.diff(oldData)
@@ -81,7 +172,7 @@ var BarView = echarts.extendChartView({
                 updateCommon(bar, opt, symbolMeta);
             })
             .update(function (newIndex, oldIndex) {
-                var bar = oldData.getItemGraphicEl(oldIndex);
+                var bar = oldData.getItemGraphicEl(oldIndex) as PictorialBarElement;
 
                 if (!data.hasValue(newIndex)) {
                     group.remove(bar);
@@ -113,24 +204,24 @@ var BarView = echarts.extendChartView({
                 updateCommon(bar, opt, symbolMeta);
             })
             .remove(function (dataIndex) {
-                var bar = oldData.getItemGraphicEl(dataIndex);
-                bar && removeBar(oldData, dataIndex, bar.__pictorialSymbolMeta.animationModel, bar);
+                var bar = oldData.getItemGraphicEl(dataIndex) as PictorialBarElement;
+                bar && removeBar(
+                    oldData, dataIndex, bar.__pictorialSymbolMeta.animationModel, bar
+                );
             })
             .execute();
 
         this._data = data;
 
         return this.group;
-    },
-
-    dispose: zrUtil.noop,
+    }
 
-    remove: function (ecModel, api) {
+    remove(ecModel: GlobalModel, api: ExtensionAPI) {
         var group = this.group;
         var data = this._data;
         if (ecModel.get('animation')) {
             if (data) {
-                data.eachItemGraphicEl(function (bar) {
+                data.eachItemGraphicEl(function (bar: PictorialBarElement & ECElement) {
                     removeBar(data, bar.dataIndex, ecModel, bar);
                 });
             }
@@ -139,12 +230,16 @@ var BarView = echarts.extendChartView({
             group.removeAll();
         }
     }
-});
-
+}
 
 // Set or calculate default value about symbol, and calculate layout info.
-function getSymbolMeta(data, dataIndex, itemModel, opt) {
-    var layout = data.getItemLayout(dataIndex);
+function getSymbolMeta(
+    data: List,
+    dataIndex: number,
+    itemModel: ItemModel,
+    opt: CreateOpts
+): SymbolMeta {
+    var layout = data.getItemLayout(dataIndex) as RectLayout;
     var symbolRepeat = itemModel.get('symbolRepeat');
     var symbolClip = itemModel.get('symbolClip');
     var symbolPosition = itemModel.get('symbolPosition') || 'start';
@@ -153,7 +248,7 @@ function getSymbolMeta(data, dataIndex, itemModel, opt) {
     var symbolPatternSize = itemModel.get('symbolPatternSize') || 2;
     var isAnimationEnabled = itemModel.isAnimationEnabled();
 
-    var symbolMeta = {
+    var symbolMeta: SymbolMeta = {
         dataIndex: dataIndex,
         layout: layout,
         itemModel: itemModel,
@@ -167,7 +262,7 @@ function getSymbolMeta(data, dataIndex, itemModel, opt) {
         animationModel: isAnimationEnabled ? itemModel : null,
         hoverAnimation: isAnimationEnabled && itemModel.get('hoverAnimation'),
         z2: itemModel.getShallow('z', true) || 0
-    };
+    } as SymbolMeta;
 
     prepareBarLength(itemModel, symbolRepeat, layout, opt, symbolMeta);
 
@@ -188,7 +283,7 @@ function getSymbolMeta(data, dataIndex, itemModel, opt) {
     }
 
     prepareLayoutInfo(
-        itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset,
+        itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset as number[],
         symbolPosition, symbolMeta.valueLineWidth, symbolMeta.boundingLength, symbolMeta.repeatCutLength,
         opt, symbolMeta
     );
@@ -197,7 +292,13 @@ function getSymbolMeta(data, dataIndex, itemModel, opt) {
 }
 
 // bar length can be negative.
-function prepareBarLength(itemModel, symbolRepeat, layout, opt, output) {
+function prepareBarLength(
+    itemModel: ItemModel,
+    symbolRepeat: PictorialBarDataItemOption['symbolRepeat'],
+    layout: RectLayout,
+    opt: CreateOpts,
+    outputSymbolMeta: SymbolMeta
+) {
     var valueDim = opt.valueDim;
     var symbolBoundingData = itemModel.get('symbolBoundingData');
     var valueAxis = opt.coordSys.getOtherAxis(opt.coordSys.getBaseAxis());
@@ -223,23 +324,31 @@ function prepareBarLength(itemModel, symbolRepeat, layout, opt, output) {
         boundingLength = layout[valueDim.wh];
     }
 
-    output.boundingLength = boundingLength;
+    outputSymbolMeta.boundingLength = boundingLength;
 
     if (symbolRepeat) {
-        output.repeatCutLength = layout[valueDim.wh];
+        outputSymbolMeta.repeatCutLength = layout[valueDim.wh];
     }
 
-    output.pxSign = boundingLength > 0 ? 1 : boundingLength < 0 ? -1 : 0;
+    outputSymbolMeta.pxSign = boundingLength > 0 ? 1 : boundingLength < 0 ? -1 : 0;
 }
 
-function convertToCoordOnAxis(axis, value) {
+function convertToCoordOnAxis(axis: Axis2D, value: number) {
     return axis.toGlobalCoord(axis.dataToCoord(axis.scale.parse(value)));
 }
 
 // Support ['100%', '100%']
 function prepareSymbolSize(
-    data, dataIndex, layout, symbolRepeat, symbolClip, boundingLength,
-    pxSign, symbolPatternSize, opt, output
+    data: List,
+    dataIndex: number,
+    layout: RectLayout,
+    symbolRepeat: PictorialBarDataItemOption['symbolRepeat'],
+    symbolClip: unknown,
+    boundingLength: number,
+    pxSign: number,
+    symbolPatternSize: number,
+    opt: CreateOpts,
+    outputSymbolMeta: SymbolMeta
 ) {
     var valueDim = opt.valueDim;
     var categoryDim = opt.categoryDim;
@@ -270,10 +379,10 @@ function prepareSymbolSize(
         symbolRepeat ? categorySize : Math.abs(boundingLength)
     );
 
-    output.symbolSize = symbolSize;
+    outputSymbolMeta.symbolSize = symbolSize;
 
     // If x or y is less than zero, show reversed shape.
-    var symbolScale = output.symbolScale = [
+    var symbolScale = outputSymbolMeta.symbolScale = [
         symbolSize[0] / symbolPatternSize,
         symbolSize[1] / symbolPatternSize
     ];
@@ -281,7 +390,13 @@ function prepareSymbolSize(
     symbolScale[valueDim.index] *= (opt.isHorizontal ? -1 : 1) * pxSign;
 }
 
-function prepareLineWidth(itemModel, symbolScale, rotation, opt, output) {
+function prepareLineWidth(
+    itemModel: ItemModel,
+    symbolScale: number[],
+    rotation: number,
+    opt: CreateOpts,
+    outputSymbolMeta: SymbolMeta
+) {
     // In symbols are drawn with scale, so do not need to care about the case that width
     // or height are too small. But symbol use strokeNoScale, where acture lineWidth should
     // be calculated.
@@ -297,16 +412,26 @@ function prepareLineWidth(itemModel, symbolScale, rotation, opt, output) {
         valueLineWidth *= symbolScale[opt.valueDim.index];
     }
 
-    output.valueLineWidth = valueLineWidth;
+    outputSymbolMeta.valueLineWidth = valueLineWidth;
 }
 
 function prepareLayoutInfo(
-    itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset,
-    symbolPosition, valueLineWidth, boundingLength, repeatCutLength, opt, output
+    itemModel: ItemModel,
+    symbolSize: number[],
+    layout: RectLayout,
+    symbolRepeat: PictorialBarDataItemOption['symbolRepeat'],
+    symbolClip: PictorialBarDataItemOption['symbolClip'],
+    symbolOffset: number[],
+    symbolPosition: PictorialBarDataItemOption['symbolPosition'],
+    valueLineWidth: number,
+    boundingLength: number,
+    repeatCutLength: number,
+    opt: CreateOpts,
+    outputSymbolMeta: SymbolMeta
 ) {
     var categoryDim = opt.categoryDim;
     var valueDim = opt.valueDim;
-    var pxSign = output.pxSign;
+    var pxSign = outputSymbolMeta.pxSign;
 
     var unitLength = Math.max(symbolSize[valueDim.index] + valueLineWidth, 0);
     var pathLen = unitLength;
@@ -316,35 +441,35 @@ function prepareLayoutInfo(
     // when rotating.
 
     if (symbolRepeat) {
-        var absBoundingLength = Math.abs(boundingLength);
+        const absBoundingLength = Math.abs(boundingLength);
 
-        var symbolMargin = zrUtil.retrieve(itemModel.get('symbolMargin'), '15%') + '';
-        var hasEndGap = false;
+        let symbolMargin = zrUtil.retrieve(itemModel.get('symbolMargin'), '15%') + '';
+        let hasEndGap = false;
         if (symbolMargin.lastIndexOf('!') === symbolMargin.length - 1) {
             hasEndGap = true;
             symbolMargin = symbolMargin.slice(0, symbolMargin.length - 1);
         }
-        symbolMargin = parsePercent(symbolMargin, symbolSize[valueDim.index]);
+        let symbolMarginNumeric = parsePercent(symbolMargin, symbolSize[valueDim.index]);
 
-        var uLenWithMargin = Math.max(unitLength + symbolMargin * 2, 0);
+        var uLenWithMargin = Math.max(unitLength + symbolMarginNumeric * 2, 0);
 
         // When symbol margin is less than 0, margin at both ends will be subtracted
         // to ensure that all of the symbols will not be overflow the given area.
-        var endFix = hasEndGap ? 0 : symbolMargin * 2;
+        var endFix = hasEndGap ? 0 : symbolMarginNumeric * 2;
 
-        // Both final repeatTimes and final symbolMargin area calculated based on
+        // Both final repeatTimes and final symbolMarginNumeric area calculated based on
         // boundingLength.
         var repeatSpecified = isNumeric(symbolRepeat);
         var repeatTimes = repeatSpecified
-            ? symbolRepeat
+            ? symbolRepeat as number
             : toIntTimes((absBoundingLength + endFix) / uLenWithMargin);
 
         // Adjust calculate margin, to ensure each symbol is displayed
         // entirely in the given layout area.
         var mDiff = absBoundingLength - repeatTimes * unitLength;
-        symbolMargin = mDiff / 2 / (hasEndGap ? repeatTimes : repeatTimes - 1);
-        uLenWithMargin = unitLength + symbolMargin * 2;
-        endFix = hasEndGap ? 0 : symbolMargin * 2;
+        symbolMarginNumeric = mDiff / 2 / (hasEndGap ? repeatTimes : repeatTimes - 1);
+        uLenWithMargin = unitLength + symbolMarginNumeric * 2;
+        endFix = hasEndGap ? 0 : symbolMarginNumeric * 2;
 
         // Update repeatTimes when not all symbol will be shown.
         if (!repeatSpecified && symbolRepeat !== 'fixed') {
@@ -354,12 +479,12 @@ function prepareLayoutInfo(
         }
 
         pathLen = repeatTimes * uLenWithMargin - endFix;
-        output.repeatTimes = repeatTimes;
-        output.symbolMargin = symbolMargin;
+        outputSymbolMeta.repeatTimes = repeatTimes;
+        outputSymbolMeta.symbolMargin = symbolMarginNumeric;
     }
 
     var sizeFix = pxSign * (pathLen / 2);
-    var pathPosition = output.pathPosition = [];
+    var pathPosition = outputSymbolMeta.pathPosition = [] as number[];
     pathPosition[categoryDim.index] = layout[categoryDim.wh] / 2;
     pathPosition[valueDim.index] = symbolPosition === 'start'
         ? sizeFix
@@ -371,17 +496,17 @@ function prepareLayoutInfo(
         pathPosition[1] += symbolOffset[1];
     }
 
-    var bundlePosition = output.bundlePosition = [];
+    var bundlePosition = outputSymbolMeta.bundlePosition = [] as number[];
     bundlePosition[categoryDim.index] = layout[categoryDim.xy];
     bundlePosition[valueDim.index] = layout[valueDim.xy];
 
-    var barRectShape = output.barRectShape = zrUtil.extend({}, layout);
+    var barRectShape = outputSymbolMeta.barRectShape = zrUtil.extend({}, layout);
     barRectShape[valueDim.wh] = pxSign * Math.max(
         Math.abs(layout[valueDim.wh]), Math.abs(pathPosition[valueDim.index] + sizeFix)
     );
     barRectShape[categoryDim.wh] = layout[categoryDim.wh];
 
-    var clipShape = output.clipShape = {};
+    var clipShape = outputSymbolMeta.clipShape = {} as RectShape;
     // Consider that symbol may be overflow layout rect.
     clipShape[categoryDim.xy] = -layout[categoryDim.xy];
     clipShape[categoryDim.wh] = opt.ecSize[categoryDim.wh];
@@ -389,7 +514,7 @@ function prepareLayoutInfo(
     clipShape[valueDim.wh] = layout[valueDim.wh];
 }
 
-function createPath(symbolMeta) {
+function createPath(symbolMeta: SymbolMeta) {
     var symbolPatternSize = symbolMeta.symbolPatternSize;
     var path = createSymbol(
         // Consider texture img, make a big size.
@@ -400,17 +525,19 @@ function createPath(symbolMeta) {
         symbolPatternSize,
         symbolMeta.color
     );
-    path.attr({
+    (path as Displayable).attr({
         culling: true
     });
     path.type !== 'image' && path.setStyle({
         strokeNoScale: true
     });
 
-    return path;
+    return path as PictorialSymbol;
 }
 
-function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) {
+function createOrUpdateRepeatSymbols(
+    bar: PictorialBarElement, opt: CreateOpts, symbolMeta: SymbolMeta, isUpdate?: boolean
+) {
     var bundle = bar.__pictorialBundle;
     var symbolSize = symbolMeta.symbolSize;
     var valueLineWidth = symbolMeta.valueLineWidth;
@@ -462,14 +589,13 @@ function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) {
 
         // FIXME
         // If all emphasis/normal through action.
-        path
-            .on('mouseover', onMouseOver)
+        path.on('mouseover', onMouseOver)
             .on('mouseout', onMouseOut);
 
         updateHoverAnimation(path, symbolMeta);
     }
 
-    function makeTarget(index) {
+    function makeTarget(index: number) {
         var position = pathPosition.slice();
         // (start && pxSign > 0) || (end && pxSign < 0): i = repeatTimes - index
         // Otherwise: i = index;
@@ -500,7 +626,12 @@ function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) {
     }
 }
 
-function createOrUpdateSingleSymbol(bar, opt, symbolMeta, isUpdate) {
+function createOrUpdateSingleSymbol(
+    bar: PictorialBarElement,
+    opt: CreateOpts,
+    symbolMeta: SymbolMeta,
+    isUpdate?: boolean
+) {
     var bundle = bar.__pictorialBundle;
     var mainPath = bar.__pictorialMainPath;
 
@@ -542,17 +673,21 @@ function createOrUpdateSingleSymbol(bar, opt, symbolMeta, isUpdate) {
 
     updateHoverAnimation(mainPath, symbolMeta);
 
-    function onMouseOver() {
+    function onMouseOver(this: typeof mainPath) {
         this.trigger('emphasis');
     }
 
-    function onMouseOut() {
+    function onMouseOut(this: typeof mainPath) {
         this.trigger('normal');
     }
 }
 
 // bar rect is used for label.
-function createOrUpdateBarRect(bar, symbolMeta, isUpdate) {
+function createOrUpdateBarRect(
+    bar: PictorialBarElement,
+    symbolMeta: SymbolMeta,
+    isUpdate?: boolean
+) {
     var rectShape = zrUtil.extend({}, symbolMeta.barRectShape);
 
     var barRect = bar.__pictorialBarRect;
@@ -575,7 +710,12 @@ function createOrUpdateBarRect(bar, symbolMeta, isUpdate) {
     }
 }
 
-function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) {
+function createOrUpdateClip(
+    bar: PictorialBarElement,
+    opt: CreateOpts,
+    symbolMeta: SymbolMeta,
+    isUpdate?: boolean
+) {
     // If not clip, symbol will be remove and rebuilt.
     if (symbolMeta.symbolClip) {
         var clipPath = bar.__pictorialClipPath;
@@ -595,7 +735,7 @@ function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) {
             bar.__pictorialBundle.setClipPath(clipPath);
             bar.__pictorialClipPath = clipPath;
 
-            var target = {};
+            var target = {} as RectShape;
             target[valueDim.wh] = symbolMeta.clipShape[valueDim.wh];
 
             graphic[isUpdate ? 'updateProps' : 'initProps'](
@@ -605,14 +745,14 @@ function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) {
     }
 }
 
-function getItemModel(data, dataIndex) {
-    var itemModel = data.getItemModel(dataIndex);
+function getItemModel(data: List, dataIndex: number) {
+    var itemModel = data.getItemModel(dataIndex) as ItemModel;
     itemModel.getAnimationDelayParams = getAnimationDelayParams;
     itemModel.isAnimationEnabled = isAnimationEnabled;
     return itemModel;
 }
 
-function getAnimationDelayParams(path) {
+function getAnimationDelayParams(this: ItemModel, path: PictorialSymbol) {
     // The order is the same as the z-order, see `symbolRepeatDiretion`.
     return {
         index: path.__pictorialAnimationIndex,
@@ -620,12 +760,12 @@ function getAnimationDelayParams(path) {
     };
 }
 
-function isAnimationEnabled() {
+function isAnimationEnabled(this: ItemModel) {
     // `animation` prop can be set on itemModel in pictorial bar chart.
     return this.parentModel.isAnimationEnabled() && !!this.getShallow('animation');
 }
 
-function updateHoverAnimation(path, symbolMeta) {
+function updateHoverAnimation(path: PictorialSymbol, symbolMeta: SymbolMeta) {
     path.off('emphasis').off('normal');
 
     var scale = symbolMeta.symbolScale.slice();
@@ -641,11 +781,12 @@ function updateHoverAnimation(path, symbolMeta) {
                 scale: scale.slice()
             }, 400, 'elasticOut');
         });
+
 }
 
-function createBar(data, opt, symbolMeta, isUpdate) {
+function createBar(data: List, opt: CreateOpts, symbolMeta: SymbolMeta, isUpdate?: boolean) {
     // bar is the main element for each data.
-    var bar = new graphic.Group();
+    var bar = new graphic.Group() as PictorialBarElement;
     // bundle is used for location and clip.
     var bundle = new graphic.Group();
     bar.add(bundle);
@@ -669,7 +810,7 @@ function createBar(data, opt, symbolMeta, isUpdate) {
     return bar;
 }
 
-function updateBar(bar, opt, symbolMeta) {
+function updateBar(bar: PictorialBarElement, opt: CreateOpts, symbolMeta: SymbolMeta) {
     var animationModel = symbolMeta.animationModel;
     var dataIndex = symbolMeta.dataIndex;
     var bundle = bar.__pictorialBundle;
@@ -690,7 +831,9 @@ function updateBar(bar, opt, symbolMeta) {
     createOrUpdateClip(bar, opt, symbolMeta, true);
 }
 
-function removeBar(data, dataIndex, animationModel, bar) {
+function removeBar(
+    data: List, dataIndex: number, animationModel: Model<AnimationOptionMixin>, bar: PictorialBarElement
+) {
     // Not show text when animating
     var labelRect = bar.__pictorialBarRect;
     labelRect && (labelRect.style.text = null);
@@ -716,7 +859,7 @@ function removeBar(data, dataIndex, animationModel, bar) {
     data.setItemGraphicEl(dataIndex, null);
 }
 
-function getShapeStr(data, symbolMeta) {
+function getShapeStr(data: List, symbolMeta: SymbolMeta) {
     return [
         data.getItemVisual(symbolMeta.dataIndex, 'symbol') || 'none',
         !!symbolMeta.symbolRepeat,
@@ -724,14 +867,25 @@ function getShapeStr(data, symbolMeta) {
     ].join(':');
 }
 
-function eachPath(bar, cb, context) {
+function eachPath<Ctx>(
+    bar: PictorialBarElement,
+    cb: (this: Ctx, el: PictorialSymbol) => void,
+    context?: Ctx
+) {
     // Do not use Group#eachChild, because it do not support remove.
     zrUtil.each(bar.__pictorialBundle.children(), function (el) {
         el !== bar.__pictorialBarRect && cb.call(context, el);
     });
 }
 
-function updateAttr(el, immediateAttrs, animationAttrs, symbolMeta, isUpdate, cb) {
+function updateAttr<T extends Element>(
+    el: T,
+    immediateAttrs: any,
+    animationAttrs: any,
+    symbolMeta: SymbolMeta,
+    isUpdate?: boolean,
+    cb?: () => void
+) {
     immediateAttrs && el.attr(immediateAttrs);
     // when symbolCip used, only clip path has init animation, otherwise it would be weird effect.
     if (symbolMeta.symbolClip && !isUpdate) {
@@ -744,14 +898,18 @@ function updateAttr(el, immediateAttrs, animationAttrs, symbolMeta, isUpdate, cb
     }
 }
 
-function updateCommon(bar, opt, symbolMeta) {
+function updateCommon(
+    bar: PictorialBarElement,
+    opt: CreateOpts,
+    symbolMeta: SymbolMeta
+) {
     var color = symbolMeta.color;
     var dataIndex = symbolMeta.dataIndex;
     var itemModel = symbolMeta.itemModel;
     // Color must be excluded.
     // Because symbol provide setColor individually to set fill and stroke
     var normalStyle = itemModel.getModel('itemStyle').getItemStyle(['color']);
-    var hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();
+    var hoverStyle = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
     var cursorStyle = itemModel.getShallow('cursor');
 
     eachPath(bar, function (path) {
@@ -782,7 +940,7 @@ function updateCommon(bar, opt, symbolMeta) {
     graphic.setHoverStyle(barRect, barRectHoverStyle);
 }
 
-function toIntTimes(times) {
+function toIntTimes(times: number) {
     var roundedTimes = Math.round(times);
     // Escapse accurate error
     return Math.abs(times - roundedTimes) < 1e-4
@@ -790,4 +948,6 @@ function toIntTimes(times) {
         : Math.ceil(times);
 }
 
-export default BarView;
\ No newline at end of file
+ComponentView.registerClass(PictorialBarView);
+
+export default PictorialBarView;
\ No newline at end of file
diff --git a/src/chart/bar/barItemStyle.ts b/src/chart/bar/barItemStyle.ts
index 7776ac6..2ab2d26 100644
--- a/src/chart/bar/barItemStyle.ts
+++ b/src/chart/bar/barItemStyle.ts
@@ -21,7 +21,7 @@ import makeStyleMapper from '../../model/mixin/makeStyleMapper';
 import { StyleProps } from 'zrender/src/graphic/Style';
 import Model from '../../model/Model';
 
-var getBarItemStyle = makeStyleMapper(
+var mapStyle = makeStyleMapper(
     [
         ['fill', 'color'],
         ['stroke', 'borderColor'],
@@ -48,14 +48,13 @@ type BarItemStyleKeys = 'fill'
     | 'shadowOffsetY'
     | 'shadowColor'
 type ItemStyleProps = Pick<StyleProps, BarItemStyleKeys>
-export default {
-    getBarItemStyle: function (this: Model, excludes?: BarItemStyleKeys[]): ItemStyleProps {
-        var style = getBarItemStyle(this, excludes);
-        if (this.getBorderLineDash) {
-            var lineDash = this.getBorderLineDash();
-            lineDash && (style.lineDash = lineDash);
-        }
-        return style;
+
+export function getBarItemStyle(model: Model, excludes?: BarItemStyleKeys[]): ItemStyleProps {
+    var style = mapStyle(model, excludes);
+    if (model.getBorderLineDash) {
+        var lineDash = model.getBorderLineDash();
+        lineDash && (style.lineDash = lineDash);
     }
-};
+    return style;
+}
 
diff --git a/src/chart/bar/helper.ts b/src/chart/bar/helper.ts
index fec4bde..ec26164 100644
--- a/src/chart/bar/helper.ts
+++ b/src/chart/bar/helper.ts
@@ -17,16 +17,25 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as graphic from '../../util/graphic';
 import {getDefaultLabel} from '../helper/labelHelper';
+import { StyleProps } from 'zrender/src/graphic/Style';
+import { LabelOption, ColorString } from '../../util/types';
+import BaseBarSeriesModel from './BaseBarSeries';
+import { BarDataItemOption } from './BarSeries';
+import Model from '../../model/Model';
 
 export function setLabel(
-    normalStyle, hoverStyle, itemModel, color, seriesModel, dataIndex, labelPositionOutside
+    normalStyle: StyleProps,
+    hoverStyle: StyleProps,
+    itemModel: Model<BarDataItemOption>,
+    color: ColorString,
+    seriesModel: BaseBarSeriesModel,
+    dataIndex: number,
+    labelPositionOutside: LabelOption['position']
 ) {
     var labelModel = itemModel.getModel('label');
-    var hoverLabelModel = itemModel.getModel('emphasis.label');
+    var hoverLabelModel = itemModel.getModel(['emphasis', 'label']);
 
     graphic.setLabelStyle(
         normalStyle, hoverStyle, labelModel, hoverLabelModel,
@@ -39,11 +48,11 @@ export function setLabel(
         }
     );
 
-    fixPosition(normalStyle);
-    fixPosition(hoverStyle);
+    fixPosition(normalStyle, labelPositionOutside);
+    fixPosition(hoverStyle, labelPositionOutside);
 }
 
-function fixPosition(style, labelPositionOutside) {
+function fixPosition(style: StyleProps, labelPositionOutside: LabelOption['position']) {
     if (style.textPosition === 'outside') {
         style.textPosition = labelPositionOutside;
     }
diff --git a/src/component/axisPointer/axisTrigger.ts b/src/component/axisPointer/axisTrigger.ts
index 2f77710..c206479 100644
--- a/src/component/axisPointer/axisTrigger.ts
+++ b/src/component/axisPointer/axisTrigger.ts
@@ -274,7 +274,7 @@ function buildPayloadsBySeries(value: AxisValue, axisInfo: CollectedAxisInfo) {
         else {
             dataIndices = series.getData().indicesOfNearest(
                 dataDim[0],
-                value,
+                value as number,
                 // Add a threshold to avoid find the wrong dataIndex
                 // when data length is not same.
                 // false,
@@ -290,7 +290,7 @@ function buildPayloadsBySeries(value: AxisValue, axisInfo: CollectedAxisInfo) {
             return;
         }
 
-        var diff = value - seriesNestestValue;
+        var diff = value as number - seriesNestestValue;
         var dist = Math.abs(diff);
         // Consider category case
         if (dist <= minDist) {
@@ -364,7 +364,7 @@ function showTooltip(
         axisIndex: axisModel.componentIndex,
         axisType: axisModel.type,
         axisId: axisModel.id,
-        value: value,
+        value: value as number,
         // Caustion: viewHelper.getValueLabel is actually on "view stage", which
         // depends that all models have been updated. So it should not be performed
         // here. Considering axisPointerModel used here is volatile, which is hard
diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts
index 91a65e2..5f6454c 100644
--- a/src/component/helper/RoamController.ts
+++ b/src/component/helper/RoamController.ts
@@ -102,7 +102,6 @@ class RoamController extends Eventful {
         const mousewheelHandler = bind(this._mousewheelHandler, this);
         const pinchHandler = bind(this._pinchHandler, this);
 
-
         /**
          * Notice: only enable needed types. For example, if 'zoom'
          * is not needed, 'zoom' should not be enabled, otherwise
diff --git a/src/component/visualMap/PiecewiseView.ts b/src/component/visualMap/PiecewiseView.ts
index 1bc7757..9129f75 100644
--- a/src/component/visualMap/PiecewiseView.ts
+++ b/src/component/visualMap/PiecewiseView.ts
@@ -56,21 +56,7 @@ class PiecewiseVisualMapView extends VisualMapView {
             thisGroup, endsText[0], itemSize, showLabel, itemAlign
         );
 
-        zrUtil.each(viewData.viewPieceList, renderItem, this);
-
-        endsText && this._renderEndsText(
-            thisGroup, endsText[1], itemSize, showLabel, itemAlign
-        );
-
-        layout.box(
-            visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap')
-        );
-
-        this.renderBackground(thisGroup);
-
-        this.positionGroup(thisGroup);
-
-        function renderItem(this: PiecewiseVisualMapView, item: typeof viewData.viewPieceList[number]) {
+        zrUtil.each(viewData.viewPieceList, function (item: typeof viewData.viewPieceList[number]) {
             var piece = item.piece;
 
             var itemGroup = new graphic.Group();
@@ -103,15 +89,29 @@ class PiecewiseVisualMapView extends VisualMapView {
             }
 
             thisGroup.add(itemGroup);
-        }
+        }, this);
+
+        endsText && this._renderEndsText(
+            thisGroup, endsText[1], itemSize, showLabel, itemAlign
+        );
+
+        layout.box(
+            visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap')
+        );
+
+        this.renderBackground(thisGroup);
+
+        this.positionGroup(thisGroup);
+
+
     }
 
     private _enableHoverLink(itemGroup: graphic.Group, pieceIndex: number) {
         itemGroup
-            .on('mouseover', zrUtil.bind(onHoverLink, this, 'highlight'))
-            .on('mouseout', zrUtil.bind(onHoverLink, this, 'downplay'));
+            .on('mouseover', () => onHoverLink('highlight'))
+            .on('mouseout', () => onHoverLink('downplay'));
 
-        function onHoverLink(this: PiecewiseVisualMapView, method?: 'highlight' | 'downplay') {
+        const onHoverLink = (method?: 'highlight' | 'downplay') => {
             var visualMapModel = this.visualMapModel;
 
             // TODO: TYPE More detailed action types
@@ -122,7 +122,7 @@ class PiecewiseVisualMapView extends VisualMapView {
                     visualMapModel
                 )
             });
-        }
+        };
     }
 
     private _getItemAlign(): helper.ItemAlign {
diff --git a/src/coord/cartesian/Cartesian2D.ts b/src/coord/cartesian/Cartesian2D.ts
index 4a69942..8105fbd 100644
--- a/src/coord/cartesian/Cartesian2D.ts
+++ b/src/coord/cartesian/Cartesian2D.ts
@@ -28,7 +28,7 @@ import GridModel from './GridModel';
 
 class Cartesian2D extends Cartesian<Axis2D> implements CoordinateSystem {
 
-    readonly type: string = 'cartesian2d';
+    readonly type = 'cartesian2d';
 
     readonly dimensions = cartesian2DDimensions;
 
diff --git a/src/data/List.ts b/src/data/List.ts
index 75afe4f..602df5e 100644
--- a/src/data/List.ts
+++ b/src/data/List.ts
@@ -21,7 +21,6 @@
 
 /**
  * List for data storage
- * @module echarts/data/List
  */
 
 import {__DEV__} from '../config';
diff --git a/src/echarts.ts b/src/echarts.ts
index 596573b..c82c1d6 100644
--- a/src/echarts.ts
+++ b/src/echarts.ts
@@ -161,7 +161,7 @@ function toLowercaseNameAndCallEventful<T>(host: T, method: EventMethodName, arg
 }
 
 
-class MessageCenter extends Eventful<MessageCenter> {}
+class MessageCenter extends Eventful {}
 var messageCenterProto = MessageCenter.prototype;
 messageCenterProto.on = createRegisterEventWithLowercaseMessageCenter('on');
 messageCenterProto.off = createRegisterEventWithLowercaseMessageCenter('off');
@@ -761,7 +761,7 @@ class ECharts {
 
     private _initEvents(): void {
         each(MOUSE_EVENT_NAMES, function (eveName) {
-            var handler = function (this: ECharts, e: ElementEvent) {
+            const handler = (e: ElementEvent) => {
                 var ecModel = this.getModel();
                 var targetEl = e.target;
                 var el = targetEl as ECElement;
diff --git a/src/layout/barGrid.ts b/src/layout/barGrid.ts
index e17ba6c..999dfe9 100644
--- a/src/layout/barGrid.ts
+++ b/src/layout/barGrid.ts
@@ -17,41 +17,78 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 /* global Float32Array */
 
 import * as zrUtil from 'zrender/src/core/util';
 import {parsePercent} from '../util/number';
 import {isDimensionStacked} from '../data/helper/dataStackHelper';
 import createRenderPlanner from '../chart/helper/createRenderPlanner';
+import BarSeriesModel from '../chart/bar/BarSeries';
+import Axis2D from '../coord/cartesian/Axis2D';
+import GlobalModel from '../model/Global';
+import type Cartesian2D from '../coord/cartesian/Cartesian2D';
+import { StageHandler, Dictionary } from '../util/types';
 
 var STACK_PREFIX = '__ec_stack_';
 var LARGE_BAR_MIN_WIDTH = 0.5;
 
 var LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array;
 
-function getSeriesStackId(seriesModel) {
+
+function getSeriesStackId(seriesModel: BarSeriesModel): string {
     return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
 }
 
-function getAxisKey(axis) {
+function getAxisKey(axis: Axis2D): string {
     return axis.dim + axis.index;
 }
 
+interface LayoutSeriesInfo {
+    bandWidth: number
+    barWidth: number
+    barMaxWidth: number
+    barMinWidth: number
+    barGap: number | string
+    barCategoryGap: number | string
+    axisKey: string
+    stackId: string
+}
+
+interface StackInfo {
+    width: number
+    maxWidth: number
+    minWidth?: number
+}
+
+/**
+ * {
+ *  [coordSysId]: {
+ *      [stackId]: {bandWidth, offset, width}
+ *  }
+ * }
+ */
+type BarWidthAndOffset = Dictionary<Dictionary<{
+    bandWidth: number
+    offset: number
+    offsetCenter: number
+    width: number
+}>>
+
+interface LayoutOption {
+    axis: Axis2D
+    count: number
+
+    barWidth?: number
+    barMaxWidth?: number
+    barMinWidth?: number
+    barGap?: number
+    barCategoryGap?: number
+}
 /**
- * @param {Object} opt
- * @param {module:echarts/coord/Axis} opt.axis Only support category axis currently.
- * @param {number} opt.count Positive interger.
- * @param {number} [opt.barWidth]
- * @param {number} [opt.barMaxWidth]
- * @param {number} [opt.barMinWidth]
- * @param {number} [opt.barGap]
- * @param {number} [opt.barCategoryGap]
  * @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined.
  */
-export function getLayoutOnAxis(opt) {
-    var params = [];
+export function getLayoutOnAxis(opt: LayoutOption) {
+    var params: LayoutSeriesInfo[] = [];
     var baseAxis = opt.axis;
     var axisKey = 'axis0';
 
@@ -65,7 +102,7 @@ export function getLayoutOnAxis(opt) {
             bandWidth: bandWidth,
             axisKey: axisKey,
             stackId: STACK_PREFIX + i
-        }, opt));
+        }, opt) as LayoutSeriesInfo);
     }
     var widthAndOffsets = doCalBarWidthAndOffset(params);
 
@@ -79,9 +116,9 @@ export function getLayoutOnAxis(opt) {
     return result;
 }
 
-export function prepareLayoutBarSeries(seriesType, ecModel) {
-    var seriesModels = [];
-    ecModel.eachSeriesByType(seriesType, function (seriesModel) {
+export function prepareLayoutBarSeries(seriesType: string, ecModel: GlobalModel): BarSeriesModel[] {
+    var seriesModels: BarSeriesModel[] = [];
+    ecModel.eachSeriesByType(seriesType, function (seriesModel: BarSeriesModel) {
         // Check series coordinate, do layout for cartesian2d only
         if (isOnCartesian(seriesModel) && !isInLargeMode(seriesModel)) {
             seriesModels.push(seriesModel);
@@ -99,7 +136,7 @@ export function prepareLayoutBarSeries(seriesType, ecModel) {
  * {'x_0': [1000000]}.
  * The value of 1000000 is in milliseconds.
  */
-function getValueAxesMinGaps(barSeries) {
+function getValueAxesMinGaps(barSeries: BarSeriesModel[]) {
     /**
      * Map from axis.index to values.
      * For a single time axis, axisValues is in the form like
@@ -107,9 +144,9 @@ function getValueAxesMinGaps(barSeries) {
      * Items in axisValues[x], e.g. 1495555200000, are time values of all
      * series.
      */
-    var axisValues = {};
+    var axisValues: Dictionary<number[]> = {};
     zrUtil.each(barSeries, function (seriesModel) {
-        var cartesian = seriesModel.coordinateSystem;
+        var cartesian = seriesModel.coordinateSystem as Cartesian2D;
         var baseAxis = cartesian.getBaseAxis();
         if (baseAxis.type !== 'time' && baseAxis.type !== 'value') {
             return;
@@ -119,7 +156,7 @@ function getValueAxesMinGaps(barSeries) {
         var key = baseAxis.dim + '_' + baseAxis.index;
         var dim = data.mapDimension(baseAxis.dim);
         for (var i = 0, cnt = data.count(); i < cnt; ++i) {
-            var value = data.get(dim, i);
+            var value = data.get(dim, i) as number;
             if (!axisValues[key]) {
                 // No previous data for the axis
                 axisValues[key] = [value];
@@ -132,7 +169,7 @@ function getValueAxesMinGaps(barSeries) {
         }
     });
 
-    var axisMinGaps = [];
+    var axisMinGaps: Dictionary<number> = {};
     for (var key in axisValues) {
         if (axisValues.hasOwnProperty(key)) {
             var valuesInAxis = axisValues[key];
@@ -158,12 +195,12 @@ function getValueAxesMinGaps(barSeries) {
     return axisMinGaps;
 }
 
-export function makeColumnLayout(barSeries) {
+export function makeColumnLayout(barSeries: BarSeriesModel[]) {
     var axisMinGaps = getValueAxesMinGaps(barSeries);
 
-    var seriesInfoList = [];
+    var seriesInfoList: LayoutSeriesInfo[] = [];
     zrUtil.each(barSeries, function (seriesModel) {
-        var cartesian = seriesModel.coordinateSystem;
+        var cartesian = seriesModel.coordinateSystem as Cartesian2D;
         var baseAxis = cartesian.getBaseAxis();
         var axisExtent = baseAxis.getExtent();
 
@@ -215,14 +252,23 @@ export function makeColumnLayout(barSeries) {
     return doCalBarWidthAndOffset(seriesInfoList);
 }
 
-function doCalBarWidthAndOffset(seriesInfoList) {
+function doCalBarWidthAndOffset(seriesInfoList: LayoutSeriesInfo[]) {
+    interface ColumnOnAxisInfo {
+        bandWidth: number
+        remainedWidth: number
+        autoWidthCount: number
+        categoryGap: number | string
+        gap: number | string
+        stacks: Dictionary<StackInfo>
+    }
+
     // Columns info on each category axis. Key is cartesian name
-    var columnsMap = {};
+    var columnsMap: Dictionary<ColumnOnAxisInfo> = {};
 
     zrUtil.each(seriesInfoList, function (seriesInfo, idx) {
         var axisKey = seriesInfo.axisKey;
         var bandWidth = seriesInfo.bandWidth;
-        var columnsOnAxis = columnsMap[axisKey] || {
+        var columnsOnAxis: ColumnOnAxisInfo = columnsMap[axisKey] || {
             bandWidth: bandWidth,
             remainedWidth: bandWidth,
             autoWidthCount: 0,
@@ -266,7 +312,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
         (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap);
     });
 
-    var result = {};
+    var result: BarWidthAndOffset = {};
 
     zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) {
 
@@ -333,7 +379,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
 
 
         var widthSum = 0;
-        var lastColumn;
+        var lastColumn: StackInfo;
         zrUtil.each(stacks, function (column, idx) {
             if (!column.width) {
                 column.width = autoWidth;
@@ -351,7 +397,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
                 bandWidth: bandWidth,
                 offset: offset,
                 width: column.width
-            };
+            } as BarWidthAndOffset[string][string];
 
             offset += column.width * (1 + barGapPercent);
         });
@@ -361,37 +407,35 @@ function doCalBarWidthAndOffset(seriesInfoList) {
 }
 
 /**
- * @param {Object} barWidthAndOffset The result of makeColumnLayout
- * @param {module:echarts/coord/Axis} axis
- * @param {module:echarts/model/Series} [seriesModel] If not provided, return all.
- * @return {Object} {stackId: {offset, width}} or {offset, width} if seriesModel provided.
+ * @param barWidthAndOffset The result of makeColumnLayout
+ * @param seriesModel If not provided, return all.
+ * @return {stackId: {offset, width}} or {offset, width} if seriesModel provided.
  */
-export function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) {
+export function retrieveColumnLayout(
+    barWidthAndOffset: BarWidthAndOffset,
+    axis: Axis2D,
+    seriesModel: BarSeriesModel
+) {
     if (barWidthAndOffset && axis) {
         var result = barWidthAndOffset[getAxisKey(axis)];
         if (result != null && seriesModel != null) {
-            result = result[getSeriesStackId(seriesModel)];
+            return result[getSeriesStackId(seriesModel)];
         }
         return result;
     }
 }
 
-/**
- * @param {string} seriesType
- * @param {module:echarts/model/Global} ecModel
- */
-export function layout(seriesType, ecModel) {
+export function layout(seriesType: string, ecModel: GlobalModel) {
 
     var seriesModels = prepareLayoutBarSeries(seriesType, ecModel);
     var barWidthAndOffset = makeColumnLayout(seriesModels);
 
-    var lastStackCoords = {};
-    var lastStackCoordsOrigin = {};
+    var lastStackCoords: Dictionary<{p: number, n: number}[]> = {};
 
     zrUtil.each(seriesModels, function (seriesModel) {
 
         var data = seriesModel.getData();
-        var cartesian = seriesModel.coordinateSystem;
+        var cartesian = seriesModel.coordinateSystem as Cartesian2D;
         var baseAxis = cartesian.getBaseAxis();
 
         var stackId = getSeriesStackId(seriesModel);
@@ -403,7 +447,6 @@ export function layout(seriesType, ecModel) {
         var barMinHeight = seriesModel.get('barMinHeight') || 0;
 
         lastStackCoords[stackId] = lastStackCoords[stackId] || [];
-        lastStackCoordsOrigin[stackId] = lastStackCoordsOrigin[stackId] || []; // Fix #4243
 
         data.setLayout({
             bandWidth: columnLayoutInfo.bandWidth,
@@ -420,9 +463,9 @@ export function layout(seriesType, ecModel) {
 
         for (var idx = 0, len = data.count(); idx < len; idx++) {
             var value = data.get(valueDim, idx);
-            var baseValue = data.get(baseDim, idx);
+            var baseValue = data.get(baseDim, idx) as number;
 
-            var sign = value >= 0 ? 'p' : 'n';
+            var sign = value >= 0 ? 'p' : 'n' as 'p' | 'n';
             var baseCoord = valueAxisStart;
 
             // Because of the barMinHeight, we can not use the value in
@@ -478,23 +521,23 @@ export function layout(seriesType, ecModel) {
             });
         }
 
-    }, this);
+    });
 }
 
 // TODO: Do not support stack in large mode yet.
-export var largeLayout = {
+export var largeLayout: StageHandler = {
 
     seriesType: 'bar',
 
     plan: createRenderPlanner(),
 
-    reset: function (seriesModel) {
+    reset: function (seriesModel: BarSeriesModel) {
         if (!isOnCartesian(seriesModel) || !isInLargeMode(seriesModel)) {
             return;
         }
 
         var data = seriesModel.getData();
-        var cartesian = seriesModel.coordinateSystem;
+        var cartesian = seriesModel.coordinateSystem as Cartesian2D;
         var coordLayout = cartesian.grid.getRect();
         var baseAxis = cartesian.getBaseAxis();
         var valueAxis = cartesian.getOtherAxis(baseAxis);
@@ -510,54 +553,56 @@ export var largeLayout = {
             barWidth = LARGE_BAR_MIN_WIDTH;
         }
 
-        return {progress: progress};
-
-        function progress(params, data) {
-            var count = params.count;
-            var largePoints = new LargeArr(count * 2);
-            var largeBackgroundPoints = new LargeArr(count * 2);
-            var largeDataIndices = new LargeArr(count);
-            var dataIndex;
-            var coord = [];
-            var valuePair = [];
-            var pointsOffset = 0;
-            var idxOffset = 0;
-
-            while ((dataIndex = params.next()) != null) {
-                valuePair[valueDimIdx] = data.get(valueDim, dataIndex);
-                valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex);
-
-                coord = cartesian.dataToPoint(valuePair, null, coord);
-                // Data index might not be in order, depends on `progressiveChunkMode`.
-                largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coordLayout.x + coordLayout.width : coord[0];
-                largePoints[pointsOffset++] = coord[0];
-                largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coord[1] : coordLayout.y + coordLayout.height;
-                largePoints[pointsOffset++] = coord[1];
-                largeDataIndices[idxOffset++] = dataIndex;
-            }
+        return {
+            progress: function (params, data) {
+                var count = params.count;
+                var largePoints = new LargeArr(count * 2);
+                var largeBackgroundPoints = new LargeArr(count * 2);
+                var largeDataIndices = new LargeArr(count);
+                var dataIndex;
+                var coord: number[] = [];
+                var valuePair = [];
+                var pointsOffset = 0;
+                var idxOffset = 0;
+
+                while ((dataIndex = params.next()) != null) {
+                    valuePair[valueDimIdx] = data.get(valueDim, dataIndex);
+                    valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex);
+
+                    coord = cartesian.dataToPoint(valuePair, null, coord);
+                    // Data index might not be in order, depends on `progressiveChunkMode`.
+                    largeBackgroundPoints[pointsOffset] =
+                        valueAxisHorizontal ? coordLayout.x + coordLayout.width : coord[0];
+                    largePoints[pointsOffset++] = coord[0];
+                    largeBackgroundPoints[pointsOffset] =
+                        valueAxisHorizontal ? coord[1] : coordLayout.y + coordLayout.height;
+                    largePoints[pointsOffset++] = coord[1];
+                    largeDataIndices[idxOffset++] = dataIndex;
+                }
 
-            data.setLayout({
-                largePoints: largePoints,
-                largeDataIndices: largeDataIndices,
-                largeBackgroundPoints: largeBackgroundPoints,
-                barWidth: barWidth,
-                valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false),
-                backgroundStart: valueAxisHorizontal ? coordLayout.x : coordLayout.y,
-                valueAxisHorizontal: valueAxisHorizontal
-            });
-        }
+                data.setLayout({
+                    largePoints: largePoints,
+                    largeDataIndices: largeDataIndices,
+                    largeBackgroundPoints: largeBackgroundPoints,
+                    barWidth: barWidth,
+                    valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false),
+                    backgroundStart: valueAxisHorizontal ? coordLayout.x : coordLayout.y,
+                    valueAxisHorizontal: valueAxisHorizontal
+                });
+            }
+        };
     }
 };
 
-function isOnCartesian(seriesModel) {
+function isOnCartesian(seriesModel: BarSeriesModel) {
     return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
 }
 
-function isInLargeMode(seriesModel) {
+function isInLargeMode(seriesModel: BarSeriesModel) {
     return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
 }
 
 // See cases in `test/bar-start.html` and `#7412`, `#8747`.
-function getValueAxisStart(baseAxis, valueAxis, stacked) {
+function getValueAxisStart(baseAxis: Axis2D, valueAxis: Axis2D, stacked?: boolean) {
     return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0));
 }
diff --git a/src/layout/barPolar.ts b/src/layout/barPolar.ts
index 6d5701e..6909a7d 100644
--- a/src/layout/barPolar.ts
+++ b/src/layout/barPolar.ts
@@ -17,33 +17,53 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as zrUtil from 'zrender/src/core/util';
 import {parsePercent} from '../util/number';
 import {isDimensionStacked} from '../data/helper/dataStackHelper';
+import type BarSeriesModel from '../chart/bar/BarSeries';
+import type Polar from '../coord/polar/Polar';
+import AngleAxis from '../coord/polar/AngleAxis';
+import RadiusAxis from '../coord/polar/RadiusAxis';
+import GlobalModel from '../model/Global';
+import ExtensionAPI from '../ExtensionAPI';
+import { Dictionary } from '../util/types';
+
+type PolarAxis = AngleAxis | RadiusAxis
+
+interface StackInfo {
+    width: number
+    maxWidth: number
+}
+interface LayoutColumnInfo {
+    autoWidthCount: number
+    bandWidth: number
+    remainedWidth: number
+    categoryGap: string | number
+    gap: string | number
+    stacks: Dictionary<StackInfo>
+}
+
+interface BarWidthAndOffset {
+    width: number
+    offset: number
+}
 
-function getSeriesStackId(seriesModel) {
+function getSeriesStackId(seriesModel: BarSeriesModel) {
     return seriesModel.get('stack')
         || '__ec_stack_' + seriesModel.seriesIndex;
 }
 
-function getAxisKey(polar, axis) {
+function getAxisKey(polar: Polar, axis: PolarAxis) {
     return axis.dim + polar.model.componentIndex;
 }
 
-/**
- * @param {string} seriesType
- * @param {module:echarts/model/Global} ecModel
- * @param {module:echarts/ExtensionAPI} api
- */
-function barLayoutPolar(seriesType, ecModel, api) {
+function barLayoutPolar(seriesType: string, ecModel: GlobalModel, api: ExtensionAPI) {
 
-    var lastStackCoords = {};
+    var lastStackCoords: Dictionary<{p: number, n: number}[]> = {};
 
     var barWidthAndOffset = calRadialBar(
         zrUtil.filter(
-            ecModel.getSeriesByType(seriesType),
+            ecModel.getSeriesByType(seriesType) as BarSeriesModel[],
             function (seriesModel) {
                 return !ecModel.isSeriesFiltered(seriesModel)
                     && seriesModel.coordinateSystem
@@ -52,7 +72,7 @@ function barLayoutPolar(seriesType, ecModel, api) {
         )
     );
 
-    ecModel.eachSeriesByType(seriesType, function (seriesModel) {
+    ecModel.eachSeriesByType(seriesType, function (seriesModel: BarSeriesModel) {
 
         // Check series coordinate, do layout for polar only
         if (seriesModel.coordinateSystem.type !== 'polar') {
@@ -60,7 +80,7 @@ function barLayoutPolar(seriesType, ecModel, api) {
         }
 
         var data = seriesModel.getData();
-        var polar = seriesModel.coordinateSystem;
+        var polar = seriesModel.coordinateSystem as Polar;
         var baseAxis = polar.getBaseAxis();
         var axisKey = getAxisKey(polar, baseAxis);
 
@@ -88,9 +108,9 @@ function barLayoutPolar(seriesType, ecModel, api) {
 
         for (var idx = 0, len = data.count(); idx < len; idx++) {
             var value = data.get(valueDim, idx);
-            var baseValue = data.get(baseDim, idx);
+            var baseValue = data.get(baseDim, idx) as number;
 
-            var sign = value >= 0 ? 'p' : 'n';
+            var sign = value >= 0 ? 'p' : 'n' as 'p' | 'n';
             var baseCoord = valueAxisStart;
 
             // Because of the barMinHeight, we can not use the value in
@@ -114,8 +134,8 @@ function barLayoutPolar(seriesType, ecModel, api) {
 
             // radial sector
             if (valueAxis.dim === 'radius') {
-                var radiusSpan = valueAxis.dataToRadius(value) - valueAxisStart;
-                var angle = baseAxis.dataToAngle(baseValue);
+                var radiusSpan = valueAxis.dataToCoord(value) - valueAxisStart;
+                var angle = baseAxis.dataToCoord(baseValue);
 
                 if (Math.abs(radiusSpan) < barMinHeight) {
                     radiusSpan = (radiusSpan < 0 ? -1 : 1) * barMinHeight;
@@ -130,8 +150,8 @@ function barLayoutPolar(seriesType, ecModel, api) {
             }
             // tangential sector
             else {
-                var angleSpan = valueAxis.dataToAngle(value, clampLayout) - valueAxisStart;
-                var radius = baseAxis.dataToRadius(baseValue);
+                var angleSpan = valueAxis.dataToCoord(value, clampLayout) - valueAxisStart;
+                var radius = baseAxis.dataToCoord(baseValue);
 
                 if (Math.abs(angleSpan) < barMinAngle) {
                     angleSpan = (angleSpan < 0 ? -1 : 1) * barMinAngle;
@@ -168,20 +188,20 @@ function barLayoutPolar(seriesType, ecModel, api) {
 
         }
 
-    }, this);
+    });
 
 }
 
 /**
  * Calculate bar width and offset for radial bar charts
  */
-function calRadialBar(barSeries, api) {
+function calRadialBar(barSeries: BarSeriesModel[]) {
     // Columns info on each category axis. Key is polar name
-    var columnsMap = {};
+    var columnsMap: Dictionary<LayoutColumnInfo> = {};
 
     zrUtil.each(barSeries, function (seriesModel, idx) {
         var data = seriesModel.getData();
-        var polar = seriesModel.coordinateSystem;
+        var polar = seriesModel.coordinateSystem as Polar;
 
         var baseAxis = polar.getBaseAxis();
         var axisKey = getAxisKey(polar, baseAxis);
@@ -235,7 +255,7 @@ function calRadialBar(barSeries, api) {
     });
 
 
-    var result = {};
+    var result: Dictionary<Dictionary<BarWidthAndOffset>> = {};
 
     zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) {
 
@@ -272,7 +292,7 @@ function calRadialBar(barSeries, api) {
         autoWidth = Math.max(autoWidth, 0);
 
         var widthSum = 0;
-        var lastColumn;
+        var lastColumn: StackInfo;
         zrUtil.each(stacks, function (column, idx) {
             if (!column.width) {
                 column.width = autoWidth;
@@ -289,7 +309,7 @@ function calRadialBar(barSeries, api) {
             result[coordSysName][stackId] = result[coordSysName][stackId] || {
                 offset: offset,
                 width: column.width
-            };
+            } as BarWidthAndOffset;
 
             offset += column.width * (1 + barGapPercent);
         });
diff --git a/src/model/Global.ts b/src/model/Global.ts
index 7f4c50f..0cb8c62 100644
--- a/src/model/Global.ts
+++ b/src/model/Global.ts
@@ -60,7 +60,7 @@ import { Dictionary } from 'zrender/src/core/types';
 var OPTION_INNER_KEY = '\0_ec_inner';
 
 
-class GlobalModel extends Model {
+class GlobalModel extends Model<ECUnitOption> {
 
     // @readonly
     option: ECUnitOption;
diff --git a/src/model/Series.ts b/src/model/Series.ts
index 80c5a5f..a1954cc 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -29,7 +29,7 @@ import {
 import * as modelUtil from '../util/model';
 import {
     DataHost, DimensionName, StageHandlerProgressParams,
-    SeriesOption, TooltipRenderMode, AxisValue, ZRColor, BoxLayoutOptionMixin
+    SeriesOption, TooltipRenderMode, ZRColor, BoxLayoutOptionMixin, ScaleDataValue
 } from '../util/types';
 import ComponentModel, { ComponentModelConstructor } from './Component';
 import {ColorPaletteMixin} from './mixin/colorPalette';
@@ -327,14 +327,10 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
         multipleSeries?: boolean,
         dataType?: string,
         renderMode?: TooltipRenderMode
-    ):
-        {
-            html: string,
-            markers: {[markName: string]: string}
-        }
-        // The override method can only return string
-        | string
-    {
+    ): {
+        html: string,
+        markers: {[markName: string]: string}
+    } | string { // The override method can only return string
 
         var series = this;
         renderMode = renderMode || 'html';
@@ -526,7 +522,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
      */
     getAxisTooltipData: (
         dim: DimensionName[],
-        value: AxisValue,
+        value: ScaleDataValue,
         baseAxis: Axis
     ) => {
         dataIndices: number[],
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 6f7ee97..9ef8e68 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -56,7 +56,8 @@ import {
     AnimationDelayCallbackParam,
     DisplayState,
     ECElement,
-    ZRRectLike
+    ZRRectLike,
+    ColorString
 } from './types';
 import GlobalModel from '../model/Global';
 
@@ -121,7 +122,7 @@ type TextCommonParams = {
      * Specify a color when color is 'auto',
      * for textFill, textStroke, textBackgroundColor, and textBorderColor. If autoColor specified, it is used as default textFill.
      */
-    autoColor?: string
+    autoColor?: ColorString
     /**
      * `true`: Use inside style (textFill, textStroke, textStrokeWidth)
      *     if `textFill` is not specified.
@@ -1067,9 +1068,9 @@ function setTokenTextStyle(
         || globalTextStyle.textShadowOffsetY;
 }
 
-function getAutoColor(color: string, opt?: {
-    autoColor?: string
-}): string {
+function getAutoColor(color: ColorString, opt?: {
+    autoColor?: ColorString
+}): ColorString {
     return color !== 'auto' ? color : (opt && opt.autoColor) ? opt.autoColor : null;
 }
 
diff --git a/src/util/symbol.ts b/src/util/symbol.ts
index 9a26e50..e5d82fe 100644
--- a/src/util/symbol.ts
+++ b/src/util/symbol.ts
@@ -345,7 +345,7 @@ export function createSymbol(
     h: number,
     color?: string,
     keepAspect?: boolean
-): graphic.Path | graphic.Image {
+) {
     // TODO Support image object, DynamicImage.
 
     var isEmpty = symbolType.indexOf('empty') === 0;
@@ -387,5 +387,5 @@ export function createSymbol(
 
     (symbolPath as ECSymbol).setColor(color);
 
-    return symbolPath;
+    return symbolPath as ECSymbol;
 }
diff --git a/src/util/throttle.ts b/src/util/throttle.ts
index 159d6ac..461c91a 100755
--- a/src/util/throttle.ts
+++ b/src/util/throttle.ts
@@ -24,7 +24,7 @@ var ORIGIN_METHOD = '\0__throttleOriginMethod';
 var RATE = '\0__throttleRate';
 var THROTTLE_TYPE = '\0__throttleType';
 
-type ThrottleFunction = () => void;
+type ThrottleFunction = (...args: any[]) => void;
 /**
  * @public
  * @param {(Function)} fn
diff --git a/src/util/types.ts b/src/util/types.ts
index df725ed..0393688 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -249,8 +249,6 @@ export type ParsedValue = ParsedValueNumeric | OrdinalRawValue;
 // will not be performed. But "scale parse" will be performed.
 export type ScaleDataValue = ParsedValue | Date;
 
-export type AxisValue = ParsedValueNumeric;
-
 // Can only be string or index, because it is used in object key in s   ome code.
 // Making the type alias here just intending to show the meaning clearly in code.
 export type DimensionIndex = number;
@@ -347,7 +345,7 @@ export type ECUnitOption = {
     media?: never
     timeline?: ComponentOption | ComponentOption[]
     [key: string]: ComponentOption | ComponentOption[] | Dictionary<any> | any
-}
+} & AnimationOptionMixin
 
 /**
  * [ECOption]:
@@ -909,8 +907,7 @@ export interface CommonAxisPointerOption {
     /**
      * 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
+    value?: ScaleDataValue
 
     status?: 'show' | 'hide'
 
@@ -998,15 +995,25 @@ export interface SeriesOption extends
 
     blendMode?: string
 
+    /**
+     * Cursor when mouse on the elements
+     */
+    cursor?: string
+
     // Needs to be override
-    data?: any;
+    data?: any
 
     legendHoverLink?: boolean
 
+    /**
+     * Configurations about progressive rendering
+     */
     progressive?: number | false
     progressiveThreshold?: number
     progressiveChunkMode?: 'mod'
-
+    /**
+     * Not available on every series
+     */
     coordinateSystem?: string
 
     // FIXME:TS more
diff --git a/src/view/Chart.ts b/src/view/Chart.ts
index 19a1ec6..f0343ea 100644
--- a/src/view/Chart.ts
+++ b/src/view/Chart.ts
@@ -41,7 +41,58 @@ var inner = modelUtil.makeInner<{
 }>();
 var renderPlanner = createRenderPlanner();
 
+interface ChartView {
+    /**
+     * Rendering preparation in progressive mode.
+     * Implement it if needed.
+     */
+    incrementalPrepareRender(
+        seriesModel: SeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        payload: Payload
+    ): void;
+
+    /**
+     * Render in progressive mode.
+     * Implement it if needed.
+     * @param params See taskParams in `stream/task.js`
+     */
+    incrementalRender(
+        params: StageHandlerProgressParams,
+        seriesModel: SeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        payload: Payload
+    ): void;
+
+    /**
+     * Update transform directly.
+     * Implement it if needed.
+     */
+    updateTransform(
+        seriesModel: SeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        payload: Payload
+    ): void | {update: true};
+
+    /**
+     * The view contains the given point.
+     * Implement it if needed.
+     */
+    containPoint(
+        point: number[], seriesModel: SeriesModel
+    ): boolean;
 
+    /**
+     * Pass only when return `true`.
+     * Implement it if needed.
+     */
+    filterForExposedEvent(
+        eventType: string, query: EventQueryItem, targetEl: Element, packedEvent: ECEvent
+    ): boolean;
+}
 class ChartView {
 
     // [Caution]: for compat the previous "class extend"
@@ -113,56 +164,6 @@ class ChartView {
      */
     dispose(ecModel: GlobalModel, api: ExtensionAPI): void {}
 
-    /**
-     * Rendering preparation in progressive mode.
-     * Implement it if needed.
-     */
-    incrementalPrepareRender: (
-        seriesModel: SeriesModel,
-        ecModel: GlobalModel,
-        api: ExtensionAPI,
-        payload: Payload
-    ) => void;
-
-    /**
-     * Render in progressive mode.
-     * Implement it if needed.
-     * @param params See taskParams in `stream/task.js`
-     */
-    incrementalRender: (
-        params: StageHandlerProgressParams,
-        seriesModel: SeriesModel,
-        ecModel: GlobalModel,
-        api: ExtensionAPI,
-        payload: Payload
-    ) => void;
-
-    /**
-     * Update transform directly.
-     * Implement it if needed.
-     */
-    updateTransform: (
-        seriesModel: SeriesModel,
-        ecModel: GlobalModel,
-        api: ExtensionAPI,
-        payload: Payload
-    ) => void | {update: true};
-
-    /**
-     * The view contains the given point.
-     * Implement it if needed.
-     */
-    containPoint: (
-        point: number[], seriesModel: SeriesModel
-    ) => boolean;
-
-    /**
-     * Pass only when return `true`.
-     * Implement it if needed.
-     */
-    filterForExposedEvent: (
-        eventType: string, query: EventQueryItem, targetEl: Element, packedEvent: ECEvent
-    ) => boolean;
 
     updateView(seriesModel: SeriesModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload): void {
         this.render(seriesModel, ecModel, api, payload);
diff --git a/src/visual/visualSolution.ts b/src/visual/visualSolution.ts
index 2922dce..693ee0e 100644
--- a/src/visual/visualSolution.ts
+++ b/src/visual/visualSolution.ts
@@ -34,7 +34,6 @@ import List from '../data/List';
 
 var each = zrUtil.each;
 
-type WithKey<T extends string, S> = { [key in T]?: S}
 type VisualMappingCollection<VisualState extends string>
     = {
         [key in VisualState]?: {
@@ -58,7 +57,7 @@ type VisualOption = {[key in BuiltinVisualProperty]?: any};
 
 
 export function createVisualMappings<VisualState extends string>(
-    option: WithKey<VisualState, VisualOption>,
+    option: Partial<Record<VisualState, VisualOption>>,
     stateList: readonly VisualState[],
     supplementVisualOption: (mappingOption: VisualMappingOption, state: string) => void
 ) {
@@ -101,7 +100,7 @@ export function createVisualMappings<VisualState extends string>(
 }
 
 export function replaceVisualOption<T extends string>(
-    thisOption: WithKey<T, any>, newOption: WithKey<T, any>, keys: readonly T[]
+    thisOption: Partial<Record<T, any>>, newOption: Partial<Record<T, any>>, keys: readonly T[]
 ) {
     // Visual attributes merge is not supported, otherwise it
     // brings overcomplicated merge logic. See #2853. So if
@@ -140,7 +139,7 @@ export function applyVisual<VisualState extends string, Scope>(
     scope?: Scope,
     dimension?: DimensionLoose
 ) {
-    var visualTypesMap: WithKey<VisualState, BuiltinVisualProperty[]> = {};
+    var visualTypesMap: Partial<Record<VisualState, BuiltinVisualProperty[]>> = {};
     zrUtil.each(stateList, function (state) {
         var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
         visualTypesMap[state] = visualTypes;
@@ -201,7 +200,7 @@ export function incrementalApplyVisual<VisualState extends string>(
     getValueState: (valueOrIndex: ParsedValue | number) => VisualState,
     dim?: DimensionLoose
 ): StageHandlerProgressExecutor {
-    var visualTypesMap: WithKey<VisualState, BuiltinVisualProperty[]> = {};
+    var visualTypesMap: Partial<Record<VisualState, BuiltinVisualProperty[]>> = {};
     zrUtil.each(stateList, function (state) {
         var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
         visualTypesMap[state] = visualTypes;


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