ソースを参照

noImplicitAny: Lower count to about 3450 (#17799)

Tobias Skarhed 6 年 前
コミット
0b9de3f761
27 ファイル変更213 行追加141 行削除
  1. 1 0
      package.json
  2. 13 12
      public/app/plugins/datasource/grafana-azure-monitor-datasource/query_ctrl.ts
  3. 5 1
      public/app/plugins/datasource/stackdriver/components/Aggregations.tsx
  4. 5 5
      public/app/plugins/datasource/stackdriver/components/QueryEditor.tsx
  5. 1 1
      public/app/plugins/datasource/stackdriver/components/SimpleSelect.tsx
  6. 5 4
      public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.test.tsx
  7. 11 8
      public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.tsx
  8. 14 5
      public/app/plugins/datasource/stackdriver/config_ctrl.ts
  9. 16 15
      public/app/plugins/datasource/stackdriver/datasource.ts
  10. 13 6
      public/app/plugins/datasource/stackdriver/filter_segments.ts
  11. 3 3
      public/app/plugins/datasource/stackdriver/functions.test.ts
  12. 21 11
      public/app/plugins/datasource/stackdriver/functions.ts
  13. 2 1
      public/app/plugins/datasource/stackdriver/query_ctrl.ts
  14. 13 11
      public/app/plugins/datasource/stackdriver/query_filter_ctrl.ts
  15. 16 10
      public/app/plugins/datasource/stackdriver/specs/datasource.test.ts
  16. 13 12
      public/app/plugins/datasource/stackdriver/specs/query_filter_ctrl.test.ts
  17. 5 0
      public/app/plugins/datasource/stackdriver/types.ts
  18. 2 2
      public/app/plugins/datasource/testdata/query_ctrl.ts
  19. 6 3
      public/app/plugins/panel/alertlist/module.ts
  20. 2 2
      public/app/plugins/panel/bargauge/BarGaugePanelEditor.tsx
  21. 12 4
      public/app/plugins/panel/dashlist/module.ts
  22. 3 3
      public/app/plugins/panel/gettingstarted/GettingStarted.tsx
  23. 1 1
      public/app/plugins/panel/graph/GraphContextMenuCtrl.ts
  24. 11 10
      public/app/plugins/panel/graph/Legend/Legend.tsx
  25. 11 10
      public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx
  26. 1 1
      scripts/ci-frontend-metrics.sh
  27. 7 0
      yarn.lock

+ 1 - 0
package.json

@@ -193,6 +193,7 @@
     "@types/enzyme-adapter-react-16": "1.0.5",
     "@types/marked": "0.6.5",
     "@types/react-redux": "^7.0.8",
+    "@types/react-test-renderer": "16.8.2",
     "@types/redux-logger": "3.0.7",
     "@types/reselect": "2.2.0",
     "@types/slate": "0.44.11",

+ 13 - 12
public/app/plugins/datasource/grafana-azure-monitor-datasource/query_ctrl.ts

@@ -6,6 +6,7 @@ import './editor/editor_component';
 
 import { TemplateSrv } from 'app/features/templating/template_srv';
 import { auto } from 'angular';
+import { SeriesData } from '@grafana/ui';
 
 export interface ResultFormat {
   text: string;
@@ -124,7 +125,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
     }
   }
 
-  onDataReceived(dataList) {
+  onDataReceived(dataList: SeriesData[]) {
     this.lastQueryError = undefined;
     this.lastQuery = '';
 
@@ -134,11 +135,11 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
     }
   }
 
-  onDataError(err) {
+  onDataError(err: any) {
     this.handleQueryCtrlError(err);
   }
 
-  handleQueryCtrlError(err) {
+  handleQueryCtrlError(err: any) {
     if (err.query && err.query.refId && err.query.refId !== this.target.refId) {
       return;
     }
@@ -196,7 +197,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
       return;
     }
 
-    return this.datasource.azureMonitorDatasource.getSubscriptions().then(subs => {
+    return this.datasource.azureMonitorDatasource.getSubscriptions().then((subs: any) => {
       this.subscriptions = subs;
       if (!this.target.subscription && this.target.queryType === 'Azure Monitor') {
         this.target.subscription = this.datasource.azureMonitorDatasource.subscriptionId;
@@ -231,7 +232,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
   }
 
   /* Azure Monitor Section */
-  getResourceGroups(query) {
+  getResourceGroups(query: any) {
     if (this.target.queryType !== 'Azure Monitor' || !this.datasource.azureMonitorDatasource.isConfigured()) {
       return;
     }
@@ -243,7 +244,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
       .catch(this.handleQueryCtrlError.bind(this));
   }
 
-  getMetricDefinitions(query) {
+  getMetricDefinitions(query: any) {
     if (
       this.target.queryType !== 'Azure Monitor' ||
       !this.target.azureMonitor.resourceGroup ||
@@ -259,7 +260,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
       .catch(this.handleQueryCtrlError.bind(this));
   }
 
-  getResourceNames(query) {
+  getResourceNames(query: any) {
     if (
       this.target.queryType !== 'Azure Monitor' ||
       !this.target.azureMonitor.resourceGroup ||
@@ -279,7 +280,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
       .catch(this.handleQueryCtrlError.bind(this));
   }
 
-  getMetricNames(query) {
+  getMetricNames(query: any) {
     if (
       this.target.queryType !== 'Azure Monitor' ||
       !this.target.azureMonitor.resourceGroup ||
@@ -345,7 +346,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
         this.replace(this.target.azureMonitor.resourceName),
         this.replace(this.target.azureMonitor.metricName)
       )
-      .then(metadata => {
+      .then((metadata: any) => {
         this.target.azureMonitor.aggOptions = metadata.supportedAggTypes || [metadata.primaryAggType];
         this.target.azureMonitor.aggregation = metadata.primaryAggType;
         this.target.azureMonitor.timeGrains = [{ text: 'auto', value: 'auto' }].concat(metadata.supportedTimeGrains);
@@ -378,7 +379,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
   getWorkspaces = () => {
     return this.datasource.azureLogAnalyticsDatasource
       .getWorkspaces(this.target.subscription)
-      .then(list => {
+      .then((list: any[]) => {
         this.workspaces = list;
         if (list.length > 0 && !this.target.azureLogAnalytics.workspace) {
           this.target.azureLogAnalytics.workspace = list[0].value;
@@ -440,7 +441,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
 
     return this.datasource
       .getAppInsightsMetricMetadata(this.replace(this.target.appInsights.metricName))
-      .then(aggData => {
+      .then((aggData: { supportedAggTypes: string[]; supportedGroupBy: string[]; primaryAggType: string }) => {
         this.target.appInsights.aggOptions = aggData.supportedAggTypes;
         this.target.appInsights.groupByOptions = aggData.supportedGroupBy;
         this.target.appInsights.aggregation = aggData.primaryAggType;
@@ -461,7 +462,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
     return this.datasource.appInsightsDatasource.getQuerySchema().catch(this.handleQueryCtrlError.bind(this));
   };
 
-  getAppInsightsGroupBySegments(query) {
+  getAppInsightsGroupBySegments(query: any) {
     return _.map(this.target.appInsights.groupByOptions, option => {
       return { text: option, value: option };
     });

+ 5 - 1
public/app/plugins/datasource/stackdriver/components/Aggregations.tsx

@@ -4,6 +4,7 @@ import _ from 'lodash';
 import { MetricSelect } from 'app/core/components/Select/MetricSelect';
 import { getAggregationOptionsByMetric } from '../functions';
 import { TemplateSrv } from 'app/features/templating/template_srv';
+import { ValueTypes, MetricKind } from '../constants';
 
 export interface Props {
   onChange: (metricDescriptor) => void;
@@ -43,7 +44,10 @@ export class Aggregations extends React.Component<Props, State> {
         {
           label: 'Aggregations',
           expanded: true,
-          options: getAggregationOptionsByMetric(metricDescriptor.valueType, metricDescriptor.metricKind).map(a => ({
+          options: getAggregationOptionsByMetric(
+            metricDescriptor.valueType as ValueTypes,
+            metricDescriptor.metricKind as MetricKind
+          ).map(a => ({
             ...a,
             label: a.text,
           })),

+ 5 - 5
public/app/plugins/datasource/stackdriver/components/QueryEditor.tsx

@@ -13,7 +13,7 @@ import { Help } from './Help';
 import { StackdriverQuery, MetricDescriptor } from '../types';
 import { getAlignmentPickerData } from '../functions';
 import StackdriverDatasource from '../datasource';
-import { SelectOptionItem } from '@grafana/ui';
+import { SelectOptionItem, TimeSeries } from '@grafana/ui';
 
 export interface Props {
   onQueryChange: (target: StackdriverQuery) => void;
@@ -71,8 +71,8 @@ export class QueryEditor extends React.Component<Props, State> {
     this.props.events.off('data-error', this.onDataError);
   }
 
-  onDataReceived(dataList) {
-    const series = dataList.find(item => item.refId === this.props.target.refId);
+  onDataReceived(dataList: TimeSeries[]) {
+    const series = dataList.find((item: any) => item.refId === this.props.target.refId);
     if (series) {
       this.setState({
         lastQuery: decodeURIComponent(series.meta.rawQuery),
@@ -82,7 +82,7 @@ export class QueryEditor extends React.Component<Props, State> {
     }
   }
 
-  onDataError(err) {
+  onDataError(err: any) {
     let lastQuery;
     let lastQueryError;
     if (err.data && err.data.error) {
@@ -123,7 +123,7 @@ export class QueryEditor extends React.Component<Props, State> {
     );
   };
 
-  onPropertyChange(prop, value) {
+  onPropertyChange(prop: string, value: string[]) {
     this.setState({ [prop]: value }, () => {
       this.props.onQueryChange(this.state);
       this.props.onExecuteQuery();

+ 1 - 1
public/app/plugins/datasource/stackdriver/components/SimpleSelect.tsx

@@ -1,7 +1,7 @@
 import React, { FC } from 'react';
 
 interface Props {
-  onValueChange: (e) => void;
+  onValueChange: (e: any) => void;
   options: any[];
   value: string;
   label: string;

+ 5 - 4
public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.test.tsx

@@ -1,21 +1,22 @@
 import React from 'react';
+// @ts-ignore
 import renderer from 'react-test-renderer';
 import { StackdriverVariableQueryEditor } from './VariableQueryEditor';
 import { VariableQueryProps } from 'app/types/plugins';
 import { MetricFindQueryTypes } from '../types';
 
 jest.mock('../functions', () => ({
-  getMetricTypes: () => ({ metricTypes: [], selectedMetricType: '' }),
-  extractServicesFromMetricDescriptors: () => [],
+  getMetricTypes: (): any => ({ metricTypes: [], selectedMetricType: '' }),
+  extractServicesFromMetricDescriptors: (): any[] => [],
 }));
 
 const props: VariableQueryProps = {
   onChange: (query, definition) => {},
   query: {},
   datasource: {
-    getMetricTypes: async p => [],
+    getMetricTypes: async (p: any): Promise<any[]> => [],
   },
-  templateSrv: { replace: s => s, variables: [] },
+  templateSrv: { replace: (s: string) => s, variables: [] },
 };
 
 describe('VariableQueryEditor', () => {

+ 11 - 8
public/app/plugins/datasource/stackdriver/components/VariableQueryEditor.tsx

@@ -63,7 +63,7 @@ export class StackdriverVariableQueryEditor extends PureComponent<VariableQueryP
     this.setState(state);
   }
 
-  async onQueryTypeChange(event) {
+  async onQueryTypeChange(event: any) {
     const state: any = {
       selectedQueryType: event.target.value,
       ...(await this.getLabels(this.state.selectedMetricType, event.target.value)),
@@ -71,7 +71,7 @@ export class StackdriverVariableQueryEditor extends PureComponent<VariableQueryP
     this.setState(state);
   }
 
-  async onServiceChange(event) {
+  async onServiceChange(event: any) {
     const { metricTypes, selectedMetricType } = getMetricTypes(
       this.state.metricDescriptors,
       this.state.selectedMetricType,
@@ -87,12 +87,12 @@ export class StackdriverVariableQueryEditor extends PureComponent<VariableQueryP
     this.setState(state);
   }
 
-  async onMetricTypeChange(event) {
+  async onMetricTypeChange(event: any) {
     const state: any = { selectedMetricType: event.target.value, ...(await this.getLabels(event.target.value)) };
     this.setState(state);
   }
 
-  onLabelKeyChange(event) {
+  onLabelKeyChange(event: any) {
     this.setState({ labelKey: event.target.value });
   }
 
@@ -102,7 +102,7 @@ export class StackdriverVariableQueryEditor extends PureComponent<VariableQueryP
     this.props.onChange(queryModel, `Stackdriver - ${query.name}`);
   }
 
-  async getLabels(selectedMetricType, selectedQueryType = this.state.selectedQueryType) {
+  async getLabels(selectedMetricType: string, selectedQueryType = this.state.selectedQueryType) {
     let result = { labels: this.state.labels, labelKey: this.state.labelKey };
     if (selectedMetricType && selectedQueryType === MetricFindQueryTypes.LabelValues) {
       const labels = await getLabelKeys(this.props.datasource, selectedMetricType);
@@ -114,12 +114,15 @@ export class StackdriverVariableQueryEditor extends PureComponent<VariableQueryP
     return result;
   }
 
-  insertTemplateVariables(options) {
-    const templateVariables = this.props.templateSrv.variables.map(v => ({ name: `$${v.name}`, value: `$${v.name}` }));
+  insertTemplateVariables(options: any) {
+    const templateVariables = this.props.templateSrv.variables.map((v: any) => ({
+      name: `$${v.name}`,
+      value: `$${v.name}`,
+    }));
     return [...templateVariables, ...options];
   }
 
-  renderQueryTypeSwitch(queryType) {
+  renderQueryTypeSwitch(queryType: string) {
     switch (queryType) {
       case MetricFindQueryTypes.MetricTypes:
         return (

+ 14 - 5
public/app/plugins/datasource/stackdriver/config_ctrl.ts

@@ -1,3 +1,12 @@
+import DatasourceSrv from 'app/features/plugins/datasource_srv';
+
+export interface JWT {
+  private_key: any;
+  token_uri: any;
+  client_email: any;
+  project_id: any;
+}
+
 export class StackdriverConfigCtrl {
   static templateUrl = 'public/app/plugins/datasource/stackdriver/partials/config.html';
   datasourceSrv: any;
@@ -9,7 +18,7 @@ export class StackdriverConfigCtrl {
   defaultAuthenticationType: string;
 
   /** @ngInject */
-  constructor(datasourceSrv) {
+  constructor(datasourceSrv: DatasourceSrv) {
     this.defaultAuthenticationType = 'jwt';
     this.datasourceSrv = datasourceSrv;
     this.current.jsonData = this.current.jsonData || {};
@@ -24,14 +33,14 @@ export class StackdriverConfigCtrl {
     ];
   }
 
-  save(jwt) {
+  save(jwt: JWT) {
     this.current.secureJsonData.privateKey = jwt.private_key;
     this.current.jsonData.tokenUri = jwt.token_uri;
     this.current.jsonData.clientEmail = jwt.client_email;
     this.current.jsonData.defaultProject = jwt.project_id;
   }
 
-  validateJwt(jwt) {
+  validateJwt(jwt: JWT) {
     this.resetValidationMessages();
     if (!jwt.private_key || jwt.private_key.length === 0) {
       this.validationErrors.push('Private key field missing in JWT file.');
@@ -57,14 +66,14 @@ export class StackdriverConfigCtrl {
     return false;
   }
 
-  onUpload(json) {
+  onUpload(json: JWT) {
     this.jsonText = '';
     if (this.validateJwt(json)) {
       this.save(json);
     }
   }
 
-  onPasteJwt(e) {
+  onPasteJwt(e: any) {
     try {
       const json = JSON.parse(e.originalEvent.clipboardData.getData('text/plain') || this.jsonText);
       if (this.validateJwt(json)) {

+ 16 - 15
public/app/plugins/datasource/stackdriver/datasource.ts

@@ -31,12 +31,12 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
     this.metricTypes = [];
   }
 
-  async getTimeSeries(options) {
+  async getTimeSeries(options: any) {
     const queries = options.targets
-      .filter(target => {
+      .filter((target: any) => {
         return !target.hide && target.metricType;
       })
-      .map(t => {
+      .map((t: any) => {
         return {
           refId: t.refId,
           intervalMs: options.intervalMs,
@@ -92,8 +92,8 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
     return response.results[refId];
   }
 
-  interpolateGroupBys(groupBys: string[], scopedVars): string[] {
-    let interpolatedGroupBys = [];
+  interpolateGroupBys(groupBys: string[], scopedVars: {}): string[] {
+    let interpolatedGroupBys: any[] = [];
     (groupBys || []).forEach(gb => {
       const interpolated = this.templateSrv.replace(gb, scopedVars || {}, 'csv').split(',');
       if (Array.isArray(interpolated)) {
@@ -109,6 +109,7 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
     let unit;
     if (targets.length > 0 && targets.every(t => t.unit === targets[0].unit)) {
       if (stackdriverUnitMappings.hasOwnProperty(targets[0].unit)) {
+        // @ts-ignore
         unit = stackdriverUnitMappings[targets[0].unit];
       }
     }
@@ -116,7 +117,7 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
   }
 
   async query(options: DataQueryRequest<StackdriverQuery>) {
-    const result = [];
+    const result: any[] = [];
     const data = await this.getTimeSeries(options);
     if (data.results) {
       Object['values'](data.results).forEach((queryRes: any) => {
@@ -143,7 +144,7 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
     }
   }
 
-  async annotationQuery(options) {
+  async annotationQuery(options: any) {
     const annotation = options.annotation;
     const queries = [
       {
@@ -156,7 +157,7 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
         text: this.templateSrv.replace(annotation.target.text, options.scopedVars || {}),
         tags: this.templateSrv.replace(annotation.target.tags, options.scopedVars || {}),
         view: 'FULL',
-        filters: (annotation.target.filters || []).map(f => {
+        filters: (annotation.target.filters || []).map((f: any) => {
           return this.templateSrv.replace(f, options.scopedVars || {});
         }),
         type: 'annotationQuery',
@@ -173,20 +174,20 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
       },
     });
 
-    const results = data.results['annotationQuery'].tables[0].rows.map(v => {
+    const results = data.results['annotationQuery'].tables[0].rows.map((v: any) => {
       return {
         annotation: annotation,
         time: Date.parse(v[0]),
         title: v[1],
         tags: [],
         text: v[3],
-      };
+      } as any;
     });
 
     return results;
   }
 
-  async metricFindQuery(query) {
+  async metricFindQuery(query: string) {
     const stackdriverMetricFindQuery = new StackdriverMetricFindQuery(this);
     return stackdriverMetricFindQuery.execute(query);
   }
@@ -224,7 +225,7 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
     }
   }
 
-  formatStackdriverError(error) {
+  formatStackdriverError(error: any) {
     let message = 'Stackdriver: ';
     message += error.statusText ? error.statusText + ': ' : '';
     if (error.data && error.data.error) {
@@ -272,7 +273,7 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
         const metricsApiPath = `v3/projects/${projectName}/metricDescriptors`;
         const { data } = await this.doRequest(`${this.baseUrl}${metricsApiPath}`);
 
-        this.metricTypes = data.metricDescriptors.map(m => {
+        this.metricTypes = data.metricDescriptors.map((m: any) => {
           const [service] = m.type.split('/');
           const [serviceShortName] = service.split('.');
           m.service = service;
@@ -290,13 +291,13 @@ export default class StackdriverDatasource extends DataSourceApi<StackdriverQuer
     }
   }
 
-  async doRequest(url, maxRetries = 1) {
+  async doRequest(url: string, maxRetries = 1) {
     return this.backendSrv
       .datasourceRequest({
         url: this.url + url,
         method: 'GET',
       })
-      .catch(error => {
+      .catch((error: any) => {
         if (maxRetries > 0) {
           return this.doRequest(url, maxRetries - 1);
         }

+ 13 - 6
public/app/plugins/datasource/stackdriver/filter_segments.ts

@@ -1,3 +1,5 @@
+import { Segment } from './types';
+
 export const DefaultRemoveFilterValue = '-- remove filter --';
 export const DefaultFilterValue = 'select value';
 
@@ -5,7 +7,12 @@ export class FilterSegments {
   filterSegments: any[];
   removeSegment: any;
 
-  constructor(private uiSegmentSrv, private filters, private getFilterKeysFunc, private getFilterValuesFunc) {}
+  constructor(
+    private uiSegmentSrv: any,
+    private filters: string[],
+    private getFilterKeysFunc: (arg0: any, arg1: string) => any,
+    private getFilterValuesFunc: (arg0: any) => any
+  ) {}
 
   buildSegmentModel() {
     this.removeSegment = this.uiSegmentSrv.newSegment({ fake: true, value: DefaultRemoveFilterValue });
@@ -30,7 +37,7 @@ export class FilterSegments {
     this.ensurePlusButton(this.filterSegments);
   }
 
-  async getFilters(segment, index, hasNoFilterKeys) {
+  async getFilters(segment: { type: any; value?: any }, index: number, hasNoFilterKeys: boolean) {
     if (segment.type === 'condition') {
       return [this.uiSegmentSrv.newSegment('AND')];
     }
@@ -70,7 +77,7 @@ export class FilterSegments {
     return filterValues;
   }
 
-  addNewFilterSegments(segment, index) {
+  addNewFilterSegments(segment: Segment, index: number) {
     if (index > 2) {
       this.filterSegments.splice(index, 0, this.uiSegmentSrv.newCondition('AND'));
     }
@@ -79,7 +86,7 @@ export class FilterSegments {
     this.filterSegments.push(this.uiSegmentSrv.newFake(DefaultFilterValue, 'value', 'query-segment-value'));
   }
 
-  removeFilterSegment(index) {
+  removeFilterSegment(index: number) {
     this.filterSegments.splice(index, 3);
     // remove trailing condition
     if (index > 2 && this.filterSegments[index - 1].type === 'condition') {
@@ -92,7 +99,7 @@ export class FilterSegments {
     }
   }
 
-  ensurePlusButton(segments) {
+  ensurePlusButton(segments: Segment[]) {
     const count = segments.length;
     const lastSegment = segments[Math.max(count - 1, 0)];
 
@@ -101,7 +108,7 @@ export class FilterSegments {
     }
   }
 
-  filterSegmentUpdated(segment, index) {
+  filterSegmentUpdated(segment: Segment, index: number) {
     if (segment.type === 'plus-button') {
       this.addNewFilterSegments(segment, index);
     } else if (segment.type === 'key' && segment.value === DefaultRemoveFilterValue) {

+ 3 - 3
public/app/plugins/datasource/stackdriver/functions.test.ts

@@ -2,7 +2,7 @@ import { getAlignmentOptionsByMetric } from './functions';
 import { ValueTypes, MetricKind } from './constants';
 
 describe('functions', () => {
-  let result;
+  let result: any;
   describe('getAlignmentOptionsByMetric', () => {
     describe('when double and gauge is passed', () => {
       beforeEach(() => {
@@ -11,7 +11,7 @@ describe('functions', () => {
 
       it('should return all alignment options except two', () => {
         expect(result.length).toBe(9);
-        expect(result.map(o => o.value)).toEqual(
+        expect(result.map((o: any) => o.value)).toEqual(
           expect.not.arrayContaining(['REDUCE_COUNT_TRUE', 'REDUCE_COUNT_FALSE'])
         );
       });
@@ -24,7 +24,7 @@ describe('functions', () => {
 
       it('should return all alignment options except four', () => {
         expect(result.length).toBe(9);
-        expect(result.map(o => o.value)).toEqual(
+        expect(result.map((o: any) => o.value)).toEqual(
           expect.not.arrayContaining([
             'ALIGN_COUNT_TRUE',
             'ALIGN_COUNT_FALSE',

+ 21 - 11
public/app/plugins/datasource/stackdriver/functions.ts

@@ -1,17 +1,24 @@
 import uniqBy from 'lodash/uniqBy';
-import { alignOptions, aggOptions } from './constants';
+import { alignOptions, aggOptions, ValueTypes, MetricKind } from './constants';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { StackdriverQuery } from './types';
 
-export const extractServicesFromMetricDescriptors = metricDescriptors => uniqBy(metricDescriptors, 'service');
+export const extractServicesFromMetricDescriptors = (metricDescriptors: any) => uniqBy(metricDescriptors, 'service');
 
-export const getMetricTypesByService = (metricDescriptors, service) =>
-  metricDescriptors.filter(m => m.service === service);
+export const getMetricTypesByService = (metricDescriptors: any, service: any) =>
+  metricDescriptors.filter((m: any) => m.service === service);
 
-export const getMetricTypes = (metricDescriptors, metricType, interpolatedMetricType, selectedService) => {
-  const metricTypes = getMetricTypesByService(metricDescriptors, selectedService).map(m => ({
+export const getMetricTypes = (
+  metricDescriptors: any[],
+  metricType: string,
+  interpolatedMetricType: any,
+  selectedService: any
+) => {
+  const metricTypes = getMetricTypesByService(metricDescriptors, selectedService).map((m: any) => ({
     value: m.type,
     name: m.displayName,
   }));
-  const metricTypeExistInArray = metricTypes.some(m => m.value === interpolatedMetricType);
+  const metricTypeExistInArray = metricTypes.some((m: any) => m.value === interpolatedMetricType);
   const selectedMetricType = metricTypeExistInArray ? metricType : metricTypes[0].value;
   return {
     metricTypes,
@@ -19,7 +26,7 @@ export const getMetricTypes = (metricDescriptors, metricType, interpolatedMetric
   };
 };
 
-export const getAlignmentOptionsByMetric = (metricValueType, metricKind) => {
+export const getAlignmentOptionsByMetric = (metricValueType: any, metricKind: any) => {
   return !metricValueType
     ? []
     : alignOptions.filter(i => {
@@ -27,7 +34,7 @@ export const getAlignmentOptionsByMetric = (metricValueType, metricKind) => {
       });
 };
 
-export const getAggregationOptionsByMetric = (valueType, metricKind) => {
+export const getAggregationOptionsByMetric = (valueType: ValueTypes, metricKind: MetricKind) => {
   return !metricKind
     ? []
     : aggOptions.filter(i => {
@@ -35,7 +42,7 @@ export const getAggregationOptionsByMetric = (valueType, metricKind) => {
       });
 };
 
-export const getLabelKeys = async (datasource, selectedMetricType) => {
+export const getLabelKeys = async (datasource: any, selectedMetricType: any) => {
   const refId = 'handleLabelKeysQuery';
   const response = await datasource.getLabels(selectedMetricType, refId);
   const labelKeys = response.meta
@@ -47,7 +54,10 @@ export const getLabelKeys = async (datasource, selectedMetricType) => {
   return labelKeys;
 };
 
-export const getAlignmentPickerData = ({ valueType, metricKind, perSeriesAligner }, templateSrv) => {
+export const getAlignmentPickerData = (
+  { valueType, metricKind, perSeriesAligner }: Partial<StackdriverQuery>,
+  templateSrv: TemplateSrv
+) => {
   const options = getAlignmentOptionsByMetric(valueType, metricKind).map(option => ({
     ...option,
     label: option.text,

+ 2 - 1
public/app/plugins/datasource/stackdriver/query_ctrl.ts

@@ -3,13 +3,14 @@ import _ from 'lodash';
 import { QueryCtrl } from 'app/plugins/sdk';
 import { StackdriverQuery } from './types';
 import { TemplateSrv } from 'app/features/templating/template_srv';
+import { auto } from 'angular';
 
 export class StackdriverQueryCtrl extends QueryCtrl {
   static templateUrl = 'partials/query.editor.html';
   templateSrv: TemplateSrv;
 
   /** @ngInject */
-  constructor($scope, $injector, templateSrv) {
+  constructor($scope: any, $injector: auto.IInjectorService, templateSrv: TemplateSrv) {
     super($scope, $injector);
     this.templateSrv = templateSrv;
     this.onQueryChange = this.onQueryChange.bind(this);

+ 13 - 11
public/app/plugins/datasource/stackdriver/query_filter_ctrl.ts

@@ -1,6 +1,8 @@
 import coreModule from 'app/core/core_module';
 import _ from 'lodash';
 import { FilterSegments, DefaultFilterValue } from './filter_segments';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { Segment } from './types';
 
 export class StackdriverFilterCtrl {
   defaultRemoveGroupByValue = '-- remove group by --';
@@ -13,11 +15,11 @@ export class StackdriverFilterCtrl {
   hideGroupBys: boolean;
   labelData: any;
   loading: Promise<any>;
-  filtersChanged: (filters) => void;
-  groupBysChanged: (groupBys) => void;
+  filtersChanged: (filters: any) => void;
+  groupBysChanged: (groupBys: any) => void;
 
   /** @ngInject */
-  constructor(private $scope, private uiSegmentSrv, private templateSrv) {
+  constructor(private $scope: any, private uiSegmentSrv: any, private templateSrv: TemplateSrv) {
     this.$scope.ctrl = this;
     this.initSegments(this.hideGroupBys);
   }
@@ -74,7 +76,7 @@ export class StackdriverFilterCtrl {
     return elements;
   }
 
-  async getFilterKeys(segment, removeText: string) {
+  async getFilterKeys(segment: { type: string }, removeText: string) {
     let elements = await this.createLabelKeyElements();
 
     if (this.filters.indexOf(this.resourceTypeValue) !== -1) {
@@ -94,7 +96,7 @@ export class StackdriverFilterCtrl {
         ];
   }
 
-  async getGroupBys(segment) {
+  async getGroupBys(segment: { type: any }) {
     let elements = await this.createLabelKeyElements();
     elements = elements.filter(e => this.groupBys.indexOf(e.value) === -1);
     const noValueOrPlusButton = !segment || segment.type === 'plus-button';
@@ -106,14 +108,14 @@ export class StackdriverFilterCtrl {
     return segment.type === 'plus-button' ? elements : [...elements, this.removeSegment];
   }
 
-  groupByChanged(segment, index) {
+  groupByChanged(segment: any, index?: number) {
     if (segment.value === this.removeSegment.value) {
       this.groupBySegments.splice(index, 1);
     } else {
       segment.type = 'value';
     }
 
-    const reducer = (memo, seg) => {
+    const reducer = (memo: any[], seg: { fake: any; value: any }) => {
       if (!seg.fake) {
         memo.push(seg.value);
       }
@@ -125,13 +127,13 @@ export class StackdriverFilterCtrl {
     this.ensurePlusButton(this.groupBySegments);
   }
 
-  async getFilters(segment, index) {
+  async getFilters(segment: { type: string }, index: number) {
     await this.loading;
     const hasNoFilterKeys = this.labelData.metricLabels && Object.keys(this.labelData.metricLabels).length === 0;
     return this.filterSegments.getFilters(segment, index, hasNoFilterKeys);
   }
 
-  getFilterValues(index) {
+  getFilterValues(index: number) {
     const filterKey = this.templateSrv.replace(this.filterSegments.filterSegments[index - 2].value);
     if (!filterKey || !this.labelData.metricLabels || Object.keys(this.labelData.metricLabels).length === 0) {
       return [];
@@ -154,14 +156,14 @@ export class StackdriverFilterCtrl {
     return [];
   }
 
-  filterSegmentUpdated(segment, index) {
+  filterSegmentUpdated(segment: { value: string; type: string }, index: number) {
     const filters = this.filterSegments.filterSegmentUpdated(segment, index);
     if (!filters.some(f => f === DefaultFilterValue)) {
       this.filtersChanged({ filters });
     }
   }
 
-  ensurePlusButton(segments) {
+  ensurePlusButton(segments: Segment[]) {
     const count = segments.length;
     const lastSegment = segments[Math.max(count - 1, 0)];
 

+ 16 - 10
public/app/plugins/datasource/stackdriver/specs/datasource.test.ts

@@ -8,6 +8,11 @@ import { StackdriverOptions } from '../types';
 import { BackendSrv } from 'app/core/services/backend_srv';
 import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
 
+interface Result {
+  status: any;
+  message?: any;
+}
+
 describe('StackdriverDataSource', () => {
   const instanceSettings = ({
     jsonData: {
@@ -20,7 +25,7 @@ describe('StackdriverDataSource', () => {
   describe('when performing testDataSource', () => {
     describe('and call to stackdriver api succeeds', () => {
       let ds;
-      let result;
+      let result: Result;
       beforeEach(async () => {
         const backendSrv = ({
           async datasourceRequest() {
@@ -37,7 +42,7 @@ describe('StackdriverDataSource', () => {
 
     describe('and a list of metricDescriptors are returned', () => {
       let ds;
-      let result;
+      let result: Result;
       beforeEach(async () => {
         const backendSrv = ({
           datasourceRequest: async () => Promise.resolve({ status: 200, data: metricDescriptors }),
@@ -52,7 +57,7 @@ describe('StackdriverDataSource', () => {
 
     describe('and call to stackdriver api fails with 400 error', () => {
       let ds;
-      let result;
+      let result: Result;
       beforeEach(async () => {
         const backendSrv = ({
           datasourceRequest: async () =>
@@ -92,8 +97,8 @@ describe('StackdriverDataSource', () => {
     };
 
     describe('and no time series data is returned', () => {
-      let ds;
-      const response = {
+      let ds: StackdriverDataSource;
+      const response: any = {
         results: {
           A: {
             refId: 'A',
@@ -114,7 +119,7 @@ describe('StackdriverDataSource', () => {
       });
 
       it('should return a list of datapoints', () => {
-        return ds.query(options).then(results => {
+        return ds.query(options as any).then(results => {
           expect(results.data.length).toBe(0);
         });
       });
@@ -124,7 +129,7 @@ describe('StackdriverDataSource', () => {
   describe('when performing getMetricTypes', () => {
     describe('and call to stackdriver api succeeds', () => {});
     let ds;
-    let result;
+    let result: any;
     beforeEach(async () => {
       const backendSrv = ({
         async datasourceRequest() {
@@ -145,6 +150,7 @@ describe('StackdriverDataSource', () => {
         },
       } as unknown) as BackendSrv;
       ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
+      // @ts-ignore
       result = await ds.getMetricTypes();
     });
     it('should return successfully', () => {
@@ -162,7 +168,7 @@ describe('StackdriverDataSource', () => {
   const noopBackendSrv = ({} as unknown) as BackendSrv;
 
   describe('when interpolating a template variable for the filter', () => {
-    let interpolated;
+    let interpolated: any[];
     describe('and is single value variable', () => {
       beforeEach(() => {
         const filterTemplateSrv = initTemplateSrv('filtervalue1');
@@ -190,7 +196,7 @@ describe('StackdriverDataSource', () => {
   });
 
   describe('when interpolating a template variable for group bys', () => {
-    let interpolated;
+    let interpolated: any[];
 
     describe('and is single value variable', () => {
       beforeEach(() => {
@@ -221,7 +227,7 @@ describe('StackdriverDataSource', () => {
   });
 
   describe('unit parsing', () => {
-    let ds, res;
+    let ds: StackdriverDataSource, res: any;
     beforeEach(() => {
       ds = new StackdriverDataSource(instanceSettings, noopBackendSrv, templateSrv, timeSrv);
     });

+ 13 - 12
public/app/plugins/datasource/stackdriver/specs/query_filter_ctrl.test.ts

@@ -3,9 +3,9 @@ import { TemplateSrvStub } from 'test/specs/helpers';
 import { DefaultRemoveFilterValue, DefaultFilterValue } from '../filter_segments';
 
 describe('StackdriverQueryFilterCtrl', () => {
-  let ctrl;
-  let result;
-  let groupByChangedMock;
+  let ctrl: Partial<StackdriverFilterCtrl>;
+  let result: any;
+  let groupByChangedMock: any;
 
   describe('when initializing query editor', () => {
     beforeEach(() => {
@@ -363,34 +363,34 @@ describe('StackdriverQueryFilterCtrl', () => {
 
 function createCtrlWithFakes(existingFilters?: string[]) {
   const fakeSegmentServer = {
-    newKey: val => {
+    newKey: (val: any) => {
       return { value: val, type: 'key' };
     },
-    newKeyValue: val => {
+    newKeyValue: (val: any) => {
       return { value: val, type: 'value' };
     },
-    newSegment: obj => {
+    newSegment: (obj: any) => {
       return { value: obj.value ? obj.value : obj };
     },
-    newOperators: ops => {
-      return ops.map(o => {
+    newOperators: (ops: any) => {
+      return ops.map((o: any) => {
         return { type: 'operator', value: o };
       });
     },
-    newFake: (value, type, cssClass) => {
+    newFake: (value: any, type: any, cssClass: any) => {
       return { value, type, cssClass };
     },
-    newOperator: op => {
+    newOperator: (op: any) => {
       return { value: op, type: 'operator' };
     },
     newPlusButton: () => {
       return { type: 'plus-button' };
     },
-    newCondition: val => {
+    newCondition: (val: any) => {
       return { type: 'condition', value: val };
     },
   };
-  const scope = {
+  const scope: any = {
     hideGroupBys: false,
     groupBys: [],
     filters: existingFilters || [],
@@ -410,5 +410,6 @@ function createCtrlWithFakes(existingFilters?: string[]) {
   };
 
   Object.assign(StackdriverFilterCtrl.prototype, scope);
+  // @ts-ignore
   return new StackdriverFilterCtrl(scope, fakeSegmentServer, new TemplateSrvStub());
 }

+ 5 - 0
public/app/plugins/datasource/stackdriver/types.ts

@@ -75,3 +75,8 @@ export interface MetricDescriptor {
   displayName: string;
   description: string;
 }
+
+export interface Segment {
+  type: string;
+  value: string;
+}

+ 2 - 2
public/app/plugins/datasource/testdata/query_ctrl.ts

@@ -33,7 +33,7 @@ export class TestDataQueryCtrl extends QueryCtrl {
     });
   }
 
-  pointSelected(option) {
+  pointSelected(option: any) {
     this.selectedPoint = option;
   }
 
@@ -53,7 +53,7 @@ export class TestDataQueryCtrl extends QueryCtrl {
   $onInit() {
     return getBackendSrv()
       .get('/api/tsdb/testdata/scenarios')
-      .then(res => {
+      .then((res: any) => {
         this.scenarioList = res;
         this.scenario = _.find(this.scenarioList, { id: this.target.scenarioId });
       });

+ 6 - 3
public/app/plugins/panel/alertlist/module.ts

@@ -4,6 +4,8 @@ import { PanelCtrl } from 'app/plugins/sdk';
 
 import * as dateMath from '@grafana/ui/src/utils/datemath';
 import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
+import { auto } from 'angular';
+import { BackendSrv } from '@grafana/runtime';
 
 class AlertListPanel extends PanelCtrl {
   static templateUrl = 'module.html';
@@ -24,7 +26,7 @@ class AlertListPanel extends PanelCtrl {
   templateSrv: string;
 
   // Set and populate defaults
-  panelDefaults = {
+  panelDefaults: any = {
     show: 'current',
     limit: 10,
     stateFilter: [],
@@ -36,7 +38,7 @@ class AlertListPanel extends PanelCtrl {
   };
 
   /** @ngInject */
-  constructor($scope, $injector, private backendSrv) {
+  constructor($scope: any, $injector: auto.IInjectorService, private backendSrv: BackendSrv) {
     super($scope, $injector);
     _.defaults(this.panel, this.panelDefaults);
 
@@ -49,9 +51,10 @@ class AlertListPanel extends PanelCtrl {
     }
   }
 
-  sortResult(alerts) {
+  sortResult(alerts: any[]) {
     if (this.panel.sortOrder === 3) {
       return _.sortBy(alerts, a => {
+        // @ts-ignore
         return alertDef.alertStateSortScore[a.state];
       });
     }

+ 2 - 2
public/app/plugins/panel/bargauge/BarGaugePanelEditor.tsx

@@ -43,8 +43,8 @@ export class BarGaugePanelEditor extends PureComponent<PanelEditorProps<BarGauge
     });
   };
 
-  onOrientationChange = ({ value }) => this.props.onOptionsChange({ ...this.props.options, orientation: value });
-  onDisplayModeChange = ({ value }) => this.props.onOptionsChange({ ...this.props.options, displayMode: value });
+  onOrientationChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, orientation: value });
+  onDisplayModeChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, displayMode: value });
 
   render() {
     const { options } = this.props;

+ 12 - 4
public/app/plugins/panel/dashlist/module.ts

@@ -1,6 +1,9 @@
 import _ from 'lodash';
 import { PanelCtrl } from 'app/plugins/sdk';
 import impressionSrv from 'app/core/services/impression_srv';
+import { auto } from 'angular';
+import { BackendSrv } from 'app/core/services/backend_srv';
+import { DashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
 
 class DashListCtrl extends PanelCtrl {
   static templateUrl = 'module.html';
@@ -9,7 +12,7 @@ class DashListCtrl extends PanelCtrl {
   groups: any[];
   modes: any[];
 
-  panelDefaults = {
+  panelDefaults: any = {
     query: '',
     limit: 10,
     tags: [],
@@ -21,7 +24,12 @@ class DashListCtrl extends PanelCtrl {
   };
 
   /** @ngInject */
-  constructor($scope, $injector, private backendSrv, private dashboardSrv) {
+  constructor(
+    $scope: any,
+    $injector: auto.IInjectorService,
+    private backendSrv: BackendSrv,
+    private dashboardSrv: DashboardSrv
+  ) {
     super($scope, $injector);
     _.defaults(this.panel, this.panelDefaults);
 
@@ -105,8 +113,8 @@ class DashListCtrl extends PanelCtrl {
     });
   }
 
-  starDashboard(dash, evt) {
-    this.dashboardSrv.starDashboard(dash.id, dash.isStarred).then(newState => {
+  starDashboard(dash: any, evt: any) {
+    this.dashboardSrv.starDashboard(dash.id, dash.isStarred).then((newState: any) => {
       dash.isStarred = newState;
     });
 

+ 3 - 3
public/app/plugins/panel/gettingstarted/GettingStarted.tsx

@@ -80,7 +80,7 @@ export class GettingStarted extends PureComponent<PanelProps, State> {
         check: () => {
           return getBackendSrv()
             .get('/api/org/users')
-            .then(res => {
+            .then((res: any) => {
               return res.length > 1;
             });
         },
@@ -93,7 +93,7 @@ export class GettingStarted extends PureComponent<PanelProps, State> {
         check: () => {
           return getBackendSrv()
             .get('/api/plugins', { embedded: 0, core: 0 })
-            .then(plugins => {
+            .then((plugins: any[]) => {
               return plugins.length > 0;
             });
         },
@@ -108,7 +108,7 @@ export class GettingStarted extends PureComponent<PanelProps, State> {
     });
   }
 
-  nextStep() {
+  nextStep(): any {
     if (this.stepIndex === this.steps.length - 1) {
       return Promise.resolve();
     }

+ 1 - 1
public/app/plugins/panel/graph/GraphContextMenuCtrl.ts

@@ -21,7 +21,7 @@ export class GraphContextMenuCtrl {
 
   isVisible: boolean;
 
-  constructor($scope) {
+  constructor($scope: any) {
     this.isVisible = false;
     this.menuItems = [];
     this.scope = $scope;

+ 11 - 10
public/app/plugins/panel/graph/Legend/Legend.tsx

@@ -4,21 +4,22 @@ import { TimeSeries } from 'app/core/core';
 import { CustomScrollbar } from '@grafana/ui';
 import { LegendItem, LEGEND_STATS } from './LegendSeriesItem';
 
+type Sort = 'min' | 'max' | 'avg' | 'current' | 'total';
 interface LegendProps {
   seriesList: TimeSeries[];
   optionalClass?: string;
 }
 
 interface LegendEventHandlers {
-  onToggleSeries?: (hiddenSeries) => void;
-  onToggleSort?: (sortBy, sortDesc) => void;
+  onToggleSeries?: (hiddenSeries: any) => void;
+  onToggleSort?: (sortBy: any, sortDesc: any) => void;
   onToggleAxis?: (series: TimeSeries) => void;
   onColorChange?: (series: TimeSeries, color: string) => void;
 }
 
 interface LegendComponentEventHandlers {
-  onToggleSeries?: (series, event) => void;
-  onToggleSort?: (sortBy, sortDesc) => void;
+  onToggleSeries?: (series: TimeSeries, event: any) => void;
+  onToggleSort?: (sortBy: Sort, sortDesc: any) => void;
   onToggleAxis?: (series: TimeSeries) => void;
   onColorChange?: (series: TimeSeries, color: string) => void;
 }
@@ -42,7 +43,7 @@ interface LegendValuesProps {
 }
 
 interface LegendSortProps {
-  sort?: 'min' | 'max' | 'avg' | 'current' | 'total';
+  sort?: Sort;
   sortDesc?: boolean;
 }
 
@@ -80,7 +81,7 @@ export class GraphLegend extends PureComponent<GraphLegendProps, LegendState> {
     onColorChange: () => {},
   };
 
-  constructor(props) {
+  constructor(props: GraphLegendProps) {
     super(props);
     this.state = {
       hiddenSeries: this.props.hiddenSeries,
@@ -104,7 +105,7 @@ export class GraphLegend extends PureComponent<GraphLegendProps, LegendState> {
     return seriesList;
   }
 
-  onToggleSeries = (series, event) => {
+  onToggleSeries = (series: TimeSeries, event: any) => {
     let hiddenSeries = { ...this.state.hiddenSeries };
     if (event.ctrlKey || event.metaKey || event.shiftKey) {
       if (hiddenSeries[series.alias]) {
@@ -119,7 +120,7 @@ export class GraphLegend extends PureComponent<GraphLegendProps, LegendState> {
     this.props.onToggleSeries(hiddenSeries);
   };
 
-  toggleSeriesExclusiveMode(series) {
+  toggleSeriesExclusiveMode(series: TimeSeries) {
     const hiddenSeries = { ...this.state.hiddenSeries };
 
     if (hiddenSeries[series.alias]) {
@@ -226,7 +227,7 @@ class LegendSeriesList extends PureComponent<LegendComponentProps> {
 }
 
 class LegendTable extends PureComponent<Partial<LegendComponentProps>> {
-  onToggleSort = stat => {
+  onToggleSort = (stat: Sort) => {
     let sortDesc = this.props.sortDesc;
     let sortBy = this.props.sort;
     if (stat !== sortBy) {
@@ -247,7 +248,7 @@ class LegendTable extends PureComponent<Partial<LegendComponentProps>> {
   render() {
     const seriesList = this.props.seriesList;
     const { values, min, max, avg, current, total, sort, sortDesc, hiddenSeries } = this.props;
-    const seriesValuesProps = { values, min, max, avg, current, total };
+    const seriesValuesProps: any = { values, min, max, avg, current, total };
     return (
       <table>
         <colgroup>

+ 11 - 10
public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx

@@ -9,9 +9,9 @@ export interface LegendLabelProps {
   series: TimeSeries;
   asTable?: boolean;
   hidden?: boolean;
-  onLabelClick?: (series, event) => void;
-  onColorChange?: (series, color: string) => void;
-  onToggleAxis?: (series) => void;
+  onLabelClick?: (series: any, event: any) => void;
+  onColorChange?: (series: any, color: string) => void;
+  onToggleAxis?: (series: any) => void;
 }
 
 export interface LegendValuesProps {
@@ -38,14 +38,14 @@ export class LegendItem extends PureComponent<LegendItemProps, LegendItemState>
     onToggleAxis: () => {},
   };
 
-  constructor(props) {
+  constructor(props: LegendItemProps) {
     super(props);
     this.state = {
       yaxis: this.props.series.yaxis,
     };
   }
 
-  onLabelClick = e => this.props.onLabelClick(this.props.series, e);
+  onLabelClick = (e: any) => this.props.onLabelClick(this.props.series, e);
 
   onToggleAxis = () => {
     const yaxis = this.state.yaxis === 2 ? 1 : 2;
@@ -54,7 +54,7 @@ export class LegendItem extends PureComponent<LegendItemProps, LegendItemState>
     this.props.onToggleAxis(info);
   };
 
-  onColorChange = color => {
+  onColorChange = (color: string) => {
     this.props.onColorChange(this.props.series, color);
     // Because of PureComponent nature it makes only shallow props comparison and changing of series.color doesn't run
     // component re-render. In this case we can't rely on color, selected by user, because it may be overwritten
@@ -66,6 +66,7 @@ export class LegendItem extends PureComponent<LegendItemProps, LegendItemState>
     const { series, asTable } = this.props;
     const legendValueItems = [];
     for (const valueName of LEGEND_STATS) {
+      // @ts-ignore
       if (this.props[valueName]) {
         const valueFormatted = series.formatValue(series.stats[valueName]);
         legendValueItems.push(
@@ -116,11 +117,11 @@ interface LegendSeriesLabelProps {
   label: string;
   color: string;
   yaxis?: number;
-  onLabelClick?: (event) => void;
+  onLabelClick?: (event: any) => void;
 }
 
 class LegendSeriesLabel extends PureComponent<LegendSeriesLabelProps & LegendSeriesIconProps> {
-  static defaultProps = {
+  static defaultProps: Partial<LegendSeriesLabelProps> = {
     yaxis: undefined,
     onLabelClick: () => {},
   };
@@ -154,12 +155,12 @@ interface LegendSeriesIconState {
   color: string;
 }
 
-function SeriesIcon({ color }) {
+function SeriesIcon({ color }: { color: string }) {
   return <i className="fa fa-minus pointer" style={{ color }} />;
 }
 
 class LegendSeriesIcon extends PureComponent<LegendSeriesIconProps, LegendSeriesIconState> {
-  static defaultProps = {
+  static defaultProps: Partial<LegendSeriesIconProps> = {
     yaxis: undefined,
     onColorChange: () => {},
     onToggleAxis: () => {},

+ 1 - 1
scripts/ci-frontend-metrics.sh

@@ -3,7 +3,7 @@
 echo -e "Collecting code stats (typescript errors & more)"
 
 
-ERROR_COUNT_LIMIT=3789
+ERROR_COUNT_LIMIT=3440
 DIRECTIVES_LIMIT=172
 CONTROLLERS_LIMIT=139
 

+ 7 - 0
yarn.lock

@@ -2187,6 +2187,13 @@
   dependencies:
     "@types/react" "*"
 
+"@types/react-test-renderer@^16.8.2":
+  version "16.8.2"
+  resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.8.2.tgz#ad544b5571ebfc5f182c320376f1431a2b725c5e"
+  integrity sha512-cm42QR9S9V3aOxLh7Fh7PUqQ8oSfSdnSni30T7TiTmlKvE6aUlo+LhQAzjnZBPriD9vYmgG8MXI8UDK4Nfb7gg==
+  dependencies:
+    "@types/react" "*"
+
 "@types/react-transition-group@*":
   version "2.9.1"
   resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.9.1.tgz#66c9ca5d0b20bae72fe6b797e0d362b996d55e9f"