瀏覽代碼

Chore: Fix about 200 noImplicitAny errors (#18067)

* Fix 200 ish errors

* Add interface
Tobias Skarhed 6 年之前
父節點
當前提交
0ef4060b98
共有 31 個文件被更改,包括 208 次插入151 次删除
  1. 13 6
      public/app/features/profile/ProfileCtrl.ts
  2. 5 2
      public/app/features/teams/CreateTeamCtrl.ts
  3. 4 4
      public/app/features/teams/TeamGroupSync.tsx
  4. 1 1
      public/app/features/teams/TeamList.tsx
  5. 1 1
      public/app/features/teams/TeamMemberRow.tsx
  6. 2 2
      public/app/features/teams/TeamMembers.tsx
  7. 1 1
      public/app/features/teams/TeamPages.tsx
  8. 5 5
      public/app/features/teams/TeamSettings.tsx
  9. 1 1
      public/app/features/teams/state/selectors.ts
  10. 1 1
      public/app/features/templating/DefaultVariableQueryEditor.tsx
  11. 7 6
      public/app/features/templating/TextBoxVariable.ts
  12. 7 7
      public/app/features/templating/adhoc_variable.ts
  13. 6 5
      public/app/features/templating/constant_variable.ts
  14. 6 5
      public/app/features/templating/custom_variable.ts
  15. 14 6
      public/app/features/templating/datasource_variable.ts
  16. 11 8
      public/app/features/templating/editor_ctrl.ts
  17. 14 5
      public/app/features/templating/interval_variable.ts
  18. 26 16
      public/app/features/templating/query_variable.ts
  19. 4 3
      public/app/features/templating/specs/editor_ctrl.test.ts
  20. 3 3
      public/app/features/templating/specs/query_variable.test.ts
  21. 7 7
      public/app/features/templating/specs/template_srv.test.ts
  22. 34 33
      public/app/features/templating/specs/variable_srv.test.ts
  23. 13 12
      public/app/features/templating/specs/variable_srv_init.test.ts
  24. 12 1
      public/app/features/templating/variable.ts
  25. 4 4
      public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts
  26. 1 1
      public/app/plugins/datasource/mssql/specs/datasource.test.ts
  27. 1 1
      public/app/plugins/datasource/mysql/specs/datasource.test.ts
  28. 1 1
      public/app/plugins/datasource/postgres/specs/datasource.test.ts
  29. 1 1
      public/app/plugins/datasource/prometheus/datasource.ts
  30. 1 1
      public/app/plugins/datasource/prometheus/specs/datasource.test.ts
  31. 1 1
      public/app/plugins/datasource/stackdriver/specs/datasource.test.ts

+ 13 - 6
public/app/features/profile/ProfileCtrl.ts

@@ -1,7 +1,9 @@
 import config from 'app/core/config';
-import { coreModule } from 'app/core/core';
+import { coreModule, NavModelSrv } from 'app/core/core';
 import { dateTime } from '@grafana/data';
 import { UserSession } from 'app/types';
+import { BackendSrv } from 'app/core/services/backend_srv';
+import { ILocationService } from 'angular';
 
 export class ProfileCtrl {
   user: any;
@@ -16,7 +18,12 @@ export class ProfileCtrl {
   navModel: any;
 
   /** @ngInject */
-  constructor(private backendSrv, private contextSrv, private $location, navModelSrv) {
+  constructor(
+    private backendSrv: BackendSrv,
+    private contextSrv: any,
+    private $location: ILocationService,
+    navModelSrv: NavModelSrv
+  ) {
     this.getUser();
     this.getUserSessions();
     this.getUserTeams();
@@ -25,7 +32,7 @@ export class ProfileCtrl {
   }
 
   getUser() {
-    this.backendSrv.get('/api/user').then(user => {
+    this.backendSrv.get('/api/user').then((user: any) => {
       this.user = user;
       this.user.theme = user.theme || 'dark';
     });
@@ -78,20 +85,20 @@ export class ProfileCtrl {
   }
 
   getUserTeams() {
-    this.backendSrv.get('/api/user/teams').then(teams => {
+    this.backendSrv.get('/api/user/teams').then((teams: any) => {
       this.teams = teams;
       this.showTeamsList = this.teams.length > 0;
     });
   }
 
   getUserOrgs() {
-    this.backendSrv.get('/api/user/orgs').then(orgs => {
+    this.backendSrv.get('/api/user/orgs').then((orgs: any) => {
       this.orgs = orgs;
       this.showOrgsList = orgs.length > 1;
     });
   }
 
-  setUsingOrg(org) {
+  setUsingOrg(org: any) {
     this.backendSrv.post('/api/user/using/' + org.orgId).then(() => {
       window.location.href = config.appSubUrl + '/profile';
     });

+ 5 - 2
public/app/features/teams/CreateTeamCtrl.ts

@@ -1,4 +1,7 @@
 import coreModule from 'app/core/core_module';
+import { BackendSrv } from 'app/core/services/backend_srv';
+import { ILocationService } from 'angular';
+import { NavModelSrv } from 'app/core/core';
 
 export class CreateTeamCtrl {
   name: string;
@@ -6,7 +9,7 @@ export class CreateTeamCtrl {
   navModel: any;
 
   /** @ngInject */
-  constructor(private backendSrv, private $location, navModelSrv) {
+  constructor(private backendSrv: BackendSrv, private $location: ILocationService, navModelSrv: NavModelSrv) {
     this.navModel = navModelSrv.getNav('cfg', 'teams', 0);
   }
 
@@ -15,7 +18,7 @@ export class CreateTeamCtrl {
       name: this.name,
       email: this.email,
     };
-    this.backendSrv.post('/api/teams', payload).then(result => {
+    this.backendSrv.post('/api/teams', payload).then((result: any) => {
       if (result.teamId) {
         this.$location.path('/org/teams/edit/' + result.teamId);
       }

+ 4 - 4
public/app/features/teams/TeamGroupSync.tsx

@@ -23,7 +23,7 @@ interface State {
 const headerTooltip = `Sync LDAP or OAuth groups with your Grafana teams.`;
 
 export class TeamGroupSync extends PureComponent<Props, State> {
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
     this.state = { isAdding: false, newGroupId: '' };
   }
@@ -40,11 +40,11 @@ export class TeamGroupSync extends PureComponent<Props, State> {
     this.setState({ isAdding: !this.state.isAdding });
   };
 
-  onNewGroupIdChanged = event => {
+  onNewGroupIdChanged = (event: any) => {
     this.setState({ newGroupId: event.target.value });
   };
 
-  onAddGroup = event => {
+  onAddGroup = (event: any) => {
     event.preventDefault();
     this.props.addTeamGroup(this.state.newGroupId);
     this.setState({ isAdding: false, newGroupId: '' });
@@ -156,7 +156,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
   }
 }
 
-function mapStateToProps(state) {
+function mapStateToProps(state: any) {
   return {
     groups: getTeamGroups(state.team),
   };

+ 1 - 1
public/app/features/teams/TeamList.tsx

@@ -154,7 +154,7 @@ export class TeamList extends PureComponent<Props, any> {
   }
 }
 
-function mapStateToProps(state) {
+function mapStateToProps(state: any) {
   return {
     navModel: getNavModel(state.navIndex, 'teams'),
     teams: getTeams(state.teams),

+ 1 - 1
public/app/features/teams/TeamMemberRow.tsx

@@ -91,7 +91,7 @@ export class TeamMemberRow extends PureComponent<Props> {
   }
 }
 
-function mapStateToProps(state) {
+function mapStateToProps(state: any) {
   return {};
 }
 

+ 2 - 2
public/app/features/teams/TeamMembers.tsx

@@ -28,7 +28,7 @@ export interface State {
 }
 
 export class TeamMembers extends PureComponent<Props, State> {
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
     this.state = { isAdding: false, newTeamMember: null };
   }
@@ -143,7 +143,7 @@ export class TeamMembers extends PureComponent<Props, State> {
   }
 }
 
-function mapStateToProps(state) {
+function mapStateToProps(state: any) {
   return {
     searchMemberQuery: getSearchMemberQuery(state.team),
     editorsCanAdmin: config.editorsCanAdmin, // this makes the feature toggle mockable/controllable from tests,

+ 1 - 1
public/app/features/teams/TeamPages.tsx

@@ -124,7 +124,7 @@ export class TeamPages extends PureComponent<Props, State> {
   }
 }
 
-function mapStateToProps(state) {
+function mapStateToProps(state: any) {
   const teamId = getRouteParamsId(state.location);
   const pageName = getRouteParamsPage(state.location) || 'members';
   const teamLoadingNav = getTeamLoadingNav(pageName as string);

+ 5 - 5
public/app/features/teams/TeamSettings.tsx

@@ -19,7 +19,7 @@ interface State {
 }
 
 export class TeamSettings extends React.Component<Props, State> {
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
 
     this.state = {
@@ -28,15 +28,15 @@ export class TeamSettings extends React.Component<Props, State> {
     };
   }
 
-  onChangeName = event => {
+  onChangeName = (event: any) => {
     this.setState({ name: event.target.value });
   };
 
-  onChangeEmail = event => {
+  onChangeEmail = (event: any) => {
     this.setState({ email: event.target.value });
   };
 
-  onUpdate = event => {
+  onUpdate = (event: any) => {
     const { name, email } = this.state;
     event.preventDefault();
     this.props.updateTeam(name, email);
@@ -86,7 +86,7 @@ export class TeamSettings extends React.Component<Props, State> {
   }
 }
 
-function mapStateToProps(state) {
+function mapStateToProps(state: any) {
   const teamId = getRouteParamsId(state.location);
 
   return {

+ 1 - 1
public/app/features/teams/state/selectors.ts

@@ -6,7 +6,7 @@ export const getSearchMemberQuery = (state: TeamState) => state.searchMemberQuer
 export const getTeamGroups = (state: TeamState) => state.groups;
 export const getTeamsCount = (state: TeamsState) => state.teams.length;
 
-export const getTeam = (state: TeamState, currentTeamId): Team | null => {
+export const getTeam = (state: TeamState, currentTeamId: any): Team | null => {
   if (state.team.id === parseInt(currentTeamId, 10)) {
     return state.team;
   }

+ 1 - 1
public/app/features/templating/DefaultVariableQueryEditor.tsx

@@ -3,7 +3,7 @@ import { Input } from '@grafana/ui';
 import { VariableQueryProps } from 'app/types/plugins';
 
 export default class DefaultVariableQueryEditor extends PureComponent<VariableQueryProps, any> {
-  constructor(props) {
+  constructor(props: VariableQueryProps) {
     super(props);
     this.state = { value: props.query };
   }

+ 7 - 6
public/app/features/templating/TextBoxVariable.ts

@@ -1,4 +1,5 @@
 import { Variable, assignModelProperties, variableTypes } from './variable';
+import { VariableSrv } from './variable_srv';
 
 export class TextBoxVariable implements Variable {
   query: string;
@@ -6,7 +7,7 @@ export class TextBoxVariable implements Variable {
   options: any[];
   skipUrlSync: boolean;
 
-  defaults = {
+  defaults: any = {
     type: 'textbox',
     name: '',
     hide: 0,
@@ -18,7 +19,7 @@ export class TextBoxVariable implements Variable {
   };
 
   /** @ngInject */
-  constructor(private model, private variableSrv) {
+  constructor(private model: any, private variableSrv: VariableSrv) {
     assignModelProperties(this, model, this.defaults);
   }
 
@@ -27,7 +28,7 @@ export class TextBoxVariable implements Variable {
     return this.model;
   }
 
-  setValue(option) {
+  setValue(option: any) {
     this.variableSrv.setOptionAsCurrent(this, option);
   }
 
@@ -37,11 +38,11 @@ export class TextBoxVariable implements Variable {
     return Promise.resolve();
   }
 
-  dependsOn(variable) {
+  dependsOn(variable: any) {
     return false;
   }
 
-  setValueFromUrl(urlValue) {
+  setValueFromUrl(urlValue: string) {
     this.query = urlValue;
     return this.variableSrv.setOptionFromUrl(this, urlValue);
   }
@@ -50,7 +51,7 @@ export class TextBoxVariable implements Variable {
     return this.current.value;
   }
 }
-
+// @ts-ignore
 variableTypes['textbox'] = {
   name: 'Text box',
   ctor: TextBoxVariable,

+ 7 - 7
public/app/features/templating/adhoc_variable.ts

@@ -5,7 +5,7 @@ export class AdhocVariable implements Variable {
   filters: any[];
   skipUrlSync: boolean;
 
-  defaults = {
+  defaults: any = {
     type: 'adhoc',
     name: '',
     label: '',
@@ -16,11 +16,11 @@ export class AdhocVariable implements Variable {
   };
 
   /** @ngInject */
-  constructor(private model) {
+  constructor(private model: any) {
     assignModelProperties(this, model, this.defaults);
   }
 
-  setValue(option) {
+  setValue(option: any) {
     return Promise.resolve();
   }
 
@@ -33,11 +33,11 @@ export class AdhocVariable implements Variable {
     return Promise.resolve();
   }
 
-  dependsOn(variable) {
+  dependsOn(variable: any) {
     return false;
   }
 
-  setValueFromUrl(urlValue) {
+  setValueFromUrl(urlValue: string[] | string[]) {
     if (!_.isArray(urlValue)) {
       urlValue = [urlValue];
     }
@@ -66,11 +66,11 @@ export class AdhocVariable implements Variable {
     });
   }
 
-  escapeDelimiter(value) {
+  escapeDelimiter(value: string) {
     return value.replace(/\|/g, '__gfp__');
   }
 
-  unescapeDelimiter(value) {
+  unescapeDelimiter(value: string) {
     return value.replace(/__gfp__/g, '|');
   }
 

+ 6 - 5
public/app/features/templating/constant_variable.ts

@@ -1,4 +1,5 @@
 import { Variable, assignModelProperties, variableTypes } from './variable';
+import { VariableSrv } from './all';
 
 export class ConstantVariable implements Variable {
   query: string;
@@ -6,7 +7,7 @@ export class ConstantVariable implements Variable {
   current: any;
   skipUrlSync: boolean;
 
-  defaults = {
+  defaults: any = {
     type: 'constant',
     name: '',
     hide: 2,
@@ -18,7 +19,7 @@ export class ConstantVariable implements Variable {
   };
 
   /** @ngInject */
-  constructor(private model, private variableSrv) {
+  constructor(private model: any, private variableSrv: VariableSrv) {
     assignModelProperties(this, model, this.defaults);
   }
 
@@ -27,7 +28,7 @@ export class ConstantVariable implements Variable {
     return this.model;
   }
 
-  setValue(option) {
+  setValue(option: any) {
     this.variableSrv.setOptionAsCurrent(this, option);
   }
 
@@ -37,11 +38,11 @@ export class ConstantVariable implements Variable {
     return Promise.resolve();
   }
 
-  dependsOn(variable) {
+  dependsOn(variable: any) {
     return false;
   }
 
-  setValueFromUrl(urlValue) {
+  setValueFromUrl(urlValue: string) {
     return this.variableSrv.setOptionFromUrl(this, urlValue);
   }
 

+ 6 - 5
public/app/features/templating/custom_variable.ts

@@ -1,5 +1,6 @@
 import _ from 'lodash';
 import { Variable, assignModelProperties, variableTypes } from './variable';
+import { VariableSrv } from './variable_srv';
 
 export class CustomVariable implements Variable {
   query: string;
@@ -9,7 +10,7 @@ export class CustomVariable implements Variable {
   current: any;
   skipUrlSync: boolean;
 
-  defaults = {
+  defaults: any = {
     type: 'custom',
     name: '',
     label: '',
@@ -24,11 +25,11 @@ export class CustomVariable implements Variable {
   };
 
   /** @ngInject */
-  constructor(private model, private variableSrv) {
+  constructor(private model: any, private variableSrv: VariableSrv) {
     assignModelProperties(this, model, this.defaults);
   }
 
-  setValue(option) {
+  setValue(option: any) {
     return this.variableSrv.setOptionAsCurrent(this, option);
   }
 
@@ -55,11 +56,11 @@ export class CustomVariable implements Variable {
     this.options.unshift({ text: 'All', value: '$__all' });
   }
 
-  dependsOn(variable) {
+  dependsOn(variable: any) {
     return false;
   }
 
-  setValueFromUrl(urlValue) {
+  setValueFromUrl(urlValue: string[]) {
     return this.variableSrv.setOptionFromUrl(this, urlValue);
   }
 

+ 14 - 6
public/app/features/templating/datasource_variable.ts

@@ -1,5 +1,8 @@
 import { Variable, containsVariable, assignModelProperties, variableTypes } from './variable';
 import { stringToJsRegex } from '@grafana/data';
+import { VariableSrv } from './variable_srv';
+import { TemplateSrv } from './template_srv';
+import { DatasourceSrv } from '../plugins/datasource_srv';
 
 export class DatasourceVariable implements Variable {
   regex: any;
@@ -11,7 +14,7 @@ export class DatasourceVariable implements Variable {
   refresh: any;
   skipUrlSync: boolean;
 
-  defaults = {
+  defaults: any = {
     type: 'datasource',
     name: '',
     hide: 0,
@@ -27,7 +30,12 @@ export class DatasourceVariable implements Variable {
   };
 
   /** @ngInject */
-  constructor(private model, private datasourceSrv, private variableSrv, private templateSrv) {
+  constructor(
+    private model: any,
+    private datasourceSrv: DatasourceSrv,
+    private variableSrv: VariableSrv,
+    private templateSrv: TemplateSrv
+  ) {
     assignModelProperties(this, model, this.defaults);
     this.refresh = 1;
   }
@@ -40,7 +48,7 @@ export class DatasourceVariable implements Variable {
     return this.model;
   }
 
-  setValue(option) {
+  setValue(option: any) {
     return this.variableSrv.setOptionAsCurrent(this, option);
   }
 
@@ -83,14 +91,14 @@ export class DatasourceVariable implements Variable {
     this.options.unshift({ text: 'All', value: '$__all' });
   }
 
-  dependsOn(variable) {
+  dependsOn(variable: any) {
     if (this.regex) {
       return containsVariable(this.regex, variable.name);
     }
     return false;
   }
 
-  setValueFromUrl(urlValue) {
+  setValueFromUrl(urlValue: string | string[]) {
     return this.variableSrv.setOptionFromUrl(this, urlValue);
   }
 
@@ -101,7 +109,7 @@ export class DatasourceVariable implements Variable {
     return this.current.value;
   }
 }
-
+// @ts-ignore
 variableTypes['datasource'] = {
   name: 'Datasource',
   ctor: DatasourceVariable,

+ 11 - 8
public/app/features/templating/editor_ctrl.ts

@@ -2,10 +2,13 @@ import _ from 'lodash';
 import coreModule from 'app/core/core_module';
 import { variableTypes } from './variable';
 import appEvents from 'app/core/app_events';
+import DatasourceSrv from '../plugins/datasource_srv';
+import { VariableSrv } from './all';
+import { TemplateSrv } from './template_srv';
 
 export class VariableEditorCtrl {
   /** @ngInject */
-  constructor($scope, datasourceSrv, variableSrv, templateSrv) {
+  constructor($scope: any, datasourceSrv: DatasourceSrv, variableSrv: VariableSrv, templateSrv: TemplateSrv) {
     $scope.variableTypes = variableTypes;
     $scope.ctrl = {};
     $scope.namePattern = /^(?!__).*$/;
@@ -36,14 +39,14 @@ export class VariableEditorCtrl {
       $scope.variables = variableSrv.variables;
       $scope.reset();
 
-      $scope.$watch('mode', val => {
+      $scope.$watch('mode', (val: string) => {
         if (val === 'new') {
           $scope.reset();
         }
       });
     };
 
-    $scope.setMode = mode => {
+    $scope.setMode = (mode: any) => {
       $scope.mode = mode;
     };
 
@@ -99,7 +102,7 @@ export class VariableEditorCtrl {
 
     $scope.runQuery = () => {
       $scope.optionsLimit = 20;
-      return variableSrv.updateOptions($scope.current).catch(err => {
+      return variableSrv.updateOptions($scope.current).catch((err: { data: { message: any }; message: string }) => {
         if (err.data && err.data.message) {
           err.message = err.data.message;
         }
@@ -107,13 +110,13 @@ export class VariableEditorCtrl {
       });
     };
 
-    $scope.onQueryChange = (query, definition) => {
+    $scope.onQueryChange = (query: any, definition: any) => {
       $scope.current.query = query;
       $scope.current.definition = definition;
       $scope.runQuery();
     };
 
-    $scope.edit = variable => {
+    $scope.edit = (variable: any) => {
       $scope.current = variable;
       $scope.currentIsNew = false;
       $scope.mode = 'edit';
@@ -123,7 +126,7 @@ export class VariableEditorCtrl {
       });
     };
 
-    $scope.duplicate = variable => {
+    $scope.duplicate = (variable: { getSaveModel: () => void; name: string }) => {
       const clone = _.cloneDeep(variable.getSaveModel());
       $scope.current = variableSrv.createVariableFromModel(clone);
       $scope.current.name = 'copy_of_' + variable.name;
@@ -173,7 +176,7 @@ export class VariableEditorCtrl {
       $scope.validate();
     };
 
-    $scope.removeVariable = variable => {
+    $scope.removeVariable = (variable: any) => {
       variableSrv.removeVariable(variable);
     };
 

+ 14 - 5
public/app/features/templating/interval_variable.ts

@@ -1,6 +1,9 @@
 import _ from 'lodash';
 import kbn from 'app/core/utils/kbn';
 import { Variable, assignModelProperties, variableTypes } from './variable';
+import { TimeSrv } from '../dashboard/services/TimeSrv';
+import { TemplateSrv } from './template_srv';
+import { VariableSrv } from './variable_srv';
 
 export class IntervalVariable implements Variable {
   name: string;
@@ -13,7 +16,7 @@ export class IntervalVariable implements Variable {
   current: any;
   skipUrlSync: boolean;
 
-  defaults = {
+  defaults: any = {
     type: 'interval',
     name: '',
     hide: 0,
@@ -29,7 +32,12 @@ export class IntervalVariable implements Variable {
   };
 
   /** @ngInject */
-  constructor(private model, private timeSrv, private templateSrv, private variableSrv) {
+  constructor(
+    private model: any,
+    private timeSrv: TimeSrv,
+    private templateSrv: TemplateSrv,
+    private variableSrv: VariableSrv
+  ) {
     assignModelProperties(this, model, this.defaults);
     this.refresh = 2;
   }
@@ -39,7 +47,7 @@ export class IntervalVariable implements Variable {
     return this.model;
   }
 
-  setValue(option) {
+  setValue(option: any) {
     this.updateAutoValue();
     return this.variableSrv.setOptionAsCurrent(this, option);
   }
@@ -74,11 +82,11 @@ export class IntervalVariable implements Variable {
     return this.variableSrv.validateVariableSelectionState(this);
   }
 
-  dependsOn(variable) {
+  dependsOn(variable: any) {
     return false;
   }
 
-  setValueFromUrl(urlValue) {
+  setValueFromUrl(urlValue: string | string[]) {
     this.updateAutoValue();
     return this.variableSrv.setOptionFromUrl(this, urlValue);
   }
@@ -88,6 +96,7 @@ export class IntervalVariable implements Variable {
   }
 }
 
+// @ts-ignore
 variableTypes['interval'] = {
   name: 'Interval',
   ctor: IntervalVariable,

+ 26 - 16
public/app/features/templating/query_variable.ts

@@ -1,6 +1,10 @@
 import _ from 'lodash';
 import { Variable, containsVariable, assignModelProperties, variableTypes } from './variable';
 import { stringToJsRegex } from '@grafana/data';
+import DatasourceSrv from '../plugins/datasource_srv';
+import { TemplateSrv } from './template_srv';
+import { VariableSrv } from './variable_srv';
+import { TimeSrv } from '../dashboard/services/TimeSrv';
 
 function getNoneOption() {
   return { text: 'None', value: '', isNone: true };
@@ -25,7 +29,7 @@ export class QueryVariable implements Variable {
   skipUrlSync: boolean;
   definition: string;
 
-  defaults = {
+  defaults: any = {
     type: 'query',
     label: null,
     query: '',
@@ -49,7 +53,13 @@ export class QueryVariable implements Variable {
   };
 
   /** @ngInject */
-  constructor(private model, private datasourceSrv, private templateSrv, private variableSrv, private timeSrv) {
+  constructor(
+    private model: any,
+    private datasourceSrv: DatasourceSrv,
+    private templateSrv: TemplateSrv,
+    private variableSrv: VariableSrv,
+    private timeSrv: TimeSrv
+  ) {
     // copy model properties to this instance
     assignModelProperties(this, model, this.defaults);
   }
@@ -66,11 +76,11 @@ export class QueryVariable implements Variable {
     return this.model;
   }
 
-  setValue(option) {
+  setValue(option: any) {
     return this.variableSrv.setOptionAsCurrent(this, option);
   }
 
-  setValueFromUrl(urlValue) {
+  setValueFromUrl(urlValue: any) {
     return this.variableSrv.setOptionFromUrl(this, urlValue);
   }
 
@@ -89,9 +99,9 @@ export class QueryVariable implements Variable {
       .then(this.variableSrv.validateVariableSelectionState.bind(this.variableSrv, this));
   }
 
-  updateTags(datasource) {
+  updateTags(datasource: any) {
     if (this.useTags) {
-      return this.metricFindQuery(datasource, this.tagsQuery).then(results => {
+      return this.metricFindQuery(datasource, this.tagsQuery).then((results: any[]) => {
         this.tags = [];
         for (let i = 0; i < results.length; i++) {
           this.tags.push(results[i].text);
@@ -105,10 +115,10 @@ export class QueryVariable implements Variable {
     return datasource;
   }
 
-  getValuesForTag(tagKey) {
+  getValuesForTag(tagKey: string) {
     return this.datasourceSrv.get(this.datasource).then(datasource => {
       const query = this.tagValuesQuery.replace('$tag', tagKey);
-      return this.metricFindQuery(datasource, query).then(results => {
+      return this.metricFindQuery(datasource, query).then((results: any) => {
         return _.map(results, value => {
           return value.text;
         });
@@ -116,8 +126,8 @@ export class QueryVariable implements Variable {
     });
   }
 
-  updateOptionsFromMetricFindQuery(datasource) {
-    return this.metricFindQuery(datasource, this.query).then(results => {
+  updateOptionsFromMetricFindQuery(datasource: any) {
+    return this.metricFindQuery(datasource, this.query).then((results: any) => {
       this.options = this.metricNamesToVariableValues(results);
       if (this.includeAll) {
         this.addAllOption();
@@ -129,8 +139,8 @@ export class QueryVariable implements Variable {
     });
   }
 
-  metricFindQuery(datasource, query) {
-    const options = { range: undefined, variable: this };
+  metricFindQuery(datasource: any, query: string) {
+    const options: any = { range: undefined, variable: this };
 
     if (this.refresh === 2) {
       options.range = this.timeSrv.timeRange();
@@ -143,7 +153,7 @@ export class QueryVariable implements Variable {
     this.options.unshift({ text: 'All', value: '$__all' });
   }
 
-  metricNamesToVariableValues(metricNames) {
+  metricNamesToVariableValues(metricNames: any[]) {
     let regex, options, i, matches;
     options = [];
 
@@ -182,7 +192,7 @@ export class QueryVariable implements Variable {
     return this.sortVariableValues(options, this.sort);
   }
 
-  sortVariableValues(options, sortOrder) {
+  sortVariableValues(options: any[], sortOrder: number) {
     if (sortOrder === 0) {
       return options;
     }
@@ -214,11 +224,11 @@ export class QueryVariable implements Variable {
     return options;
   }
 
-  dependsOn(variable) {
+  dependsOn(variable: any) {
     return containsVariable(this.query, this.datasource, this.regex, variable.name);
   }
 }
-
+// @ts-ignore
 variableTypes['query'] = {
   name: 'Query',
   ctor: QueryVariable,

+ 4 - 3
public/app/features/templating/specs/editor_ctrl.test.ts

@@ -1,6 +1,7 @@
 import { VariableEditorCtrl } from '../editor_ctrl';
+import { TemplateSrv } from '../template_srv';
 
-let mockEmit;
+let mockEmit: any;
 jest.mock('app/core/app_events', () => {
   mockEmit = jest.fn();
   return {
@@ -17,7 +18,7 @@ describe('VariableEditorCtrl', () => {
 
   describe('When running a variable query and the data source returns an error', () => {
     beforeEach(() => {
-      const variableSrv = {
+      const variableSrv: any = {
         updateOptions: () => {
           return Promise.reject({
             data: { message: 'error' },
@@ -25,7 +26,7 @@ describe('VariableEditorCtrl', () => {
         },
       };
 
-      return new VariableEditorCtrl(scope, {}, variableSrv, {});
+      return new VariableEditorCtrl(scope, {} as any, variableSrv, {} as TemplateSrv);
     });
 
     it('should emit an error', () => {

+ 3 - 3
public/app/features/templating/specs/query_variable.test.ts

@@ -41,7 +41,7 @@ describe('QueryVariable', () => {
 
   describe('can convert and sort metric names', () => {
     const variable = new QueryVariable({}, null, null, null, null);
-    let input;
+    let input: any;
 
     beforeEach(() => {
       input = [
@@ -61,7 +61,7 @@ describe('QueryVariable', () => {
     });
 
     describe('can sort a mixed array of metric variables in numeric order', () => {
-      let result;
+      let result: any;
 
       beforeEach(() => {
         variable.sort = 3; // Numerical (asc)
@@ -82,7 +82,7 @@ describe('QueryVariable', () => {
     });
 
     describe('can sort a mixed array of metric variables in alphabetical order', () => {
-      let result;
+      let result: any;
 
       beforeEach(() => {
         variable.sort = 5; // Alphabetical CI (asc)

+ 7 - 7
public/app/features/templating/specs/template_srv.test.ts

@@ -1,9 +1,9 @@
 import { TemplateSrv } from '../template_srv';
 
 describe('templateSrv', () => {
-  let _templateSrv;
+  let _templateSrv: any;
 
-  function initTemplateSrv(variables) {
+  function initTemplateSrv(variables: any) {
     _templateSrv = new TemplateSrv();
     _templateSrv.init(variables);
   }
@@ -374,7 +374,7 @@ describe('templateSrv', () => {
     });
 
     it('should set multiple url params', () => {
-      const params = {};
+      const params: any = {};
       _templateSrv.fillVariableValuesForUrl(params);
       expect(params['var-test']).toMatchObject(['val1', 'val2']);
     });
@@ -395,7 +395,7 @@ describe('templateSrv', () => {
     });
 
     it('should not include template variable value in url', () => {
-      const params = {};
+      const params: any = {};
       _templateSrv.fillVariableValuesForUrl(params);
       expect(params['var-test']).toBe(undefined);
     });
@@ -417,7 +417,7 @@ describe('templateSrv', () => {
     });
 
     it('should not include template variable value in url', () => {
-      const params = {};
+      const params: any = {};
       _templateSrv.fillVariableValuesForUrl(params);
       expect(params['var-test']).toBe(undefined);
     });
@@ -429,7 +429,7 @@ describe('templateSrv', () => {
     });
 
     it('should set scoped value as url params', () => {
-      const params = {};
+      const params: any = {};
       _templateSrv.fillVariableValuesForUrl(params, {
         test: { value: 'val1' },
       });
@@ -443,7 +443,7 @@ describe('templateSrv', () => {
     });
 
     it('should not set scoped value as url params', () => {
-      const params = {};
+      const params: any = {};
       _templateSrv.fillVariableValuesForUrl(params, {
         test: { name: 'test', value: 'val1', skipUrlSync: true },
       });

+ 34 - 33
public/app/features/templating/specs/variable_srv.test.ts

@@ -1,6 +1,7 @@
 import '../all';
 import { VariableSrv } from '../variable_srv';
 import { DashboardModel } from '../../dashboard/state/DashboardModel';
+// @ts-ignore
 import $q from 'q';
 import { dateTime } from '@grafana/data';
 import { CustomVariable } from '../custom_variable';
@@ -17,16 +18,16 @@ describe('VariableSrv', function(this: any) {
       $on: () => {},
     },
     $injector: {
-      instantiate: (ctr, obj) => new ctr(obj.model),
+      instantiate: (ctr: any, obj: { model: any }) => new ctr(obj.model),
     },
     templateSrv: {
       setGrafanaVariable: jest.fn(),
-      init: vars => {
+      init: (vars: any) => {
         this.variables = vars;
       },
       updateIndex: () => {},
-      replace: str =>
-        str.replace(this.regex, match => {
+      replace: (str: any) =>
+        str.replace(this.regex, (match: string) => {
           return match;
         }),
     },
@@ -35,10 +36,10 @@ describe('VariableSrv', function(this: any) {
     },
   } as any;
 
-  function describeUpdateVariable(desc, fn) {
+  function describeUpdateVariable(desc: string, fn: Function) {
     describe(desc, () => {
       const scenario: any = {};
-      scenario.setup = setupFn => {
+      scenario.setup = (setupFn: Function) => {
         scenario.setupFn = setupFn;
       };
 
@@ -56,7 +57,7 @@ describe('VariableSrv', function(this: any) {
           getMetricSources: () => scenario.metricSources,
         };
 
-        ctx.$injector.instantiate = (ctr, model) => {
+        ctx.$injector.instantiate = (ctr: any, model: any) => {
           return getVarMockConstructor(ctr, model, ctx);
         };
 
@@ -77,7 +78,7 @@ describe('VariableSrv', function(this: any) {
     });
   }
 
-  describeUpdateVariable('interval variable without auto', scenario => {
+  describeUpdateVariable('interval variable without auto', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'interval',
@@ -96,7 +97,7 @@ describe('VariableSrv', function(this: any) {
   //
   // Interval variable update
   //
-  describeUpdateVariable('interval variable with auto', scenario => {
+  describeUpdateVariable('interval variable with auto', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'interval',
@@ -141,7 +142,7 @@ describe('VariableSrv', function(this: any) {
   //
   // Query variable update
   //
-  describeUpdateVariable('query variable with empty current object and refresh', scenario => {
+  describeUpdateVariable('query variable with empty current object and refresh', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -160,7 +161,7 @@ describe('VariableSrv', function(this: any) {
 
   describeUpdateVariable(
     'query variable with multi select and new options does not contain some selected values',
-    scenario => {
+    (scenario: any) => {
       scenario.setup(() => {
         scenario.variableModel = {
           type: 'query',
@@ -183,7 +184,7 @@ describe('VariableSrv', function(this: any) {
 
   describeUpdateVariable(
     'query variable with multi select and new options does not contain any selected values',
-    scenario => {
+    (scenario: any) => {
       scenario.setup(() => {
         scenario.variableModel = {
           type: 'query',
@@ -204,7 +205,7 @@ describe('VariableSrv', function(this: any) {
     }
   );
 
-  describeUpdateVariable('query variable with multi select and $__all selected', scenario => {
+  describeUpdateVariable('query variable with multi select and $__all selected', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -225,7 +226,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('query variable with numeric results', scenario => {
+  describeUpdateVariable('query variable with numeric results', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -243,7 +244,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('basic query variable', scenario => {
+  describeUpdateVariable('basic query variable', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
       scenario.queryResult = [{ text: 'backend1' }, { text: 'backend2' }];
@@ -261,7 +262,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('and existing value still exists in options', scenario => {
+  describeUpdateVariable('and existing value still exists in options', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
       scenario.variableModel.current = { value: 'backend2', text: 'backend2' };
@@ -273,7 +274,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('and regex pattern exists', scenario => {
+  describeUpdateVariable('and regex pattern exists', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
       scenario.variableModel.regex = '/apps.*(backend_[0-9]+)/';
@@ -288,7 +289,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('and regex pattern exists and no match', scenario => {
+  describeUpdateVariable('and regex pattern exists and no match', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
       scenario.variableModel.regex = '/apps.*(backendasd[0-9]+)/';
@@ -304,7 +305,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('regex pattern without slashes', scenario => {
+  describeUpdateVariable('regex pattern without slashes', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
       scenario.variableModel.regex = 'backend_01';
@@ -319,7 +320,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('regex pattern remove duplicates', scenario => {
+  describeUpdateVariable('regex pattern remove duplicates', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = { type: 'query', query: 'apps.*', name: 'test' };
       scenario.variableModel.regex = '/backend_01/';
@@ -334,7 +335,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('with include All', scenario => {
+  describeUpdateVariable('with include All', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -351,7 +352,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('with include all and custom value', scenario => {
+  describeUpdateVariable('with include all and custom value', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -368,7 +369,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('without sort', scenario => {
+  describeUpdateVariable('without sort', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -386,7 +387,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('with alphabetical sort (asc)', scenario => {
+  describeUpdateVariable('with alphabetical sort (asc)', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -404,7 +405,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('with alphabetical sort (desc)', scenario => {
+  describeUpdateVariable('with alphabetical sort (desc)', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -422,7 +423,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('with numerical sort (asc)', scenario => {
+  describeUpdateVariable('with numerical sort (asc)', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -440,7 +441,7 @@ describe('VariableSrv', function(this: any) {
     });
   });
 
-  describeUpdateVariable('with numerical sort (desc)', scenario => {
+  describeUpdateVariable('with numerical sort (desc)', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'query',
@@ -461,7 +462,7 @@ describe('VariableSrv', function(this: any) {
   //
   // datasource variable update
   //
-  describeUpdateVariable('datasource variable with regex filter', scenario => {
+  describeUpdateVariable('datasource variable with regex filter', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'datasource',
@@ -492,7 +493,7 @@ describe('VariableSrv', function(this: any) {
   //
   // Custom variable update
   //
-  describeUpdateVariable('update custom variable', scenario => {
+  describeUpdateVariable('update custom variable', (scenario: any) => {
     scenario.setup(() => {
       scenario.variableModel = {
         type: 'custom',
@@ -511,7 +512,7 @@ describe('VariableSrv', function(this: any) {
   });
 
   describe('multiple interval variables with auto', () => {
-    let variable1, variable2;
+    let variable1: any, variable2: any;
 
     beforeEach(() => {
       const range = {
@@ -624,7 +625,7 @@ describe('VariableSrv', function(this: any) {
   });
 });
 
-function setupSetFromUrlTest(ctx, model = {}) {
+function setupSetFromUrlTest(ctx: any, model = {}) {
   const variableSrv = new VariableSrv($q, ctx.$location, ctx.$injector, ctx.templateSrv, ctx.timeSrv);
   const finalModel = {
     type: 'custom',
@@ -636,10 +637,10 @@ function setupSetFromUrlTest(ctx, model = {}) {
   // We are mocking the setValue here instead of just checking the final variable.current value because there is lots
   // of stuff going when the setValue is called that is hard to mock out.
   variable.setValue = jest.fn();
-  return [variable.setValue, val => variableSrv.setOptionFromUrl(variable, val)];
+  return [variable.setValue, (val: any) => variableSrv.setOptionFromUrl(variable, val)];
 }
 
-function getVarMockConstructor(variable, model, ctx) {
+function getVarMockConstructor(variable: any, model: any, ctx: any) {
   switch (model.model.type) {
     case 'datasource':
       return new variable(model.model, ctx.datasourceSrv, ctx.variableSrv, ctx.templateSrv);

+ 13 - 12
public/app/features/templating/specs/variable_srv_init.test.ts

@@ -3,16 +3,17 @@ import '../all';
 import _ from 'lodash';
 import { VariableSrv } from '../variable_srv';
 import { DashboardModel } from '../../dashboard/state/DashboardModel';
+// @ts-ignore
 import $q from 'q';
 
 describe('VariableSrv init', function(this: any) {
   const templateSrv = {
-    init: vars => {
+    init: (vars: any) => {
       this.variables = vars;
     },
     variableInitialized: () => {},
     updateIndex: () => {},
-    replace: str =>
+    replace: (str: string) =>
       str.replace(this.regex, match => {
         return match;
       }),
@@ -27,11 +28,11 @@ describe('VariableSrv init', function(this: any) {
   const $injector = {} as any;
   let ctx = {} as any;
 
-  function describeInitScenario(desc, fn) {
+  function describeInitScenario(desc: string, fn: Function) {
     describe(desc, () => {
       const scenario: any = {
         urlParams: {},
-        setup: setupFn => {
+        setup: (setupFn: Function) => {
           scenario.setupFn = setupFn;
         },
       };
@@ -52,7 +53,7 @@ describe('VariableSrv init', function(this: any) {
         // @ts-ignore
         ctx.variableSrv = new VariableSrv($q, {}, $injector, templateSrv, timeSrv);
 
-        $injector.instantiate = (variable, model) => {
+        $injector.instantiate = (variable: any, model: any) => {
           return getVarMockConstructor(variable, model, ctx);
         };
 
@@ -74,7 +75,7 @@ describe('VariableSrv init', function(this: any) {
   }
 
   ['query', 'interval', 'custom', 'datasource'].forEach(type => {
-    describeInitScenario('when setting ' + type + ' variable via url', scenario => {
+    describeInitScenario('when setting ' + type + ' variable via url', (scenario: any) => {
       scenario.setup(() => {
         scenario.variables = [
           {
@@ -114,7 +115,7 @@ describe('VariableSrv init', function(this: any) {
       },
     ];
 
-    describeInitScenario('when setting parent const from url', scenario => {
+    describeInitScenario('when setting parent const from url', (scenario: any) => {
       scenario.setup(() => {
         scenario.variables = _.cloneDeep(variableList);
         scenario.urlParams['var-app'] = 'google';
@@ -132,7 +133,7 @@ describe('VariableSrv init', function(this: any) {
     });
   });
 
-  describeInitScenario('when datasource variable is initialized', scenario => {
+  describeInitScenario('when datasource variable is initialized', (scenario: any) => {
     scenario.setup(() => {
       scenario.variables = [
         {
@@ -157,7 +158,7 @@ describe('VariableSrv init', function(this: any) {
     });
   });
 
-  describeInitScenario('when template variable is present in url multiple times', scenario => {
+  describeInitScenario('when template variable is present in url multiple times', (scenario: any) => {
     scenario.setup(() => {
       scenario.variables = [
         {
@@ -193,7 +194,7 @@ describe('VariableSrv init', function(this: any) {
 
   describeInitScenario(
     'when template variable is present in url multiple times and variables have no text',
-    scenario => {
+    (scenario: any) => {
       scenario.setup(() => {
         scenario.variables = [
           {
@@ -215,7 +216,7 @@ describe('VariableSrv init', function(this: any) {
     }
   );
 
-  describeInitScenario('when template variable is present in url multiple times using key/values', scenario => {
+  describeInitScenario('when template variable is present in url multiple times using key/values', (scenario: any) => {
     scenario.setup(() => {
       scenario.variables = [
         {
@@ -250,7 +251,7 @@ describe('VariableSrv init', function(this: any) {
   });
 });
 
-function getVarMockConstructor(variable, model, ctx) {
+function getVarMockConstructor(variable: any, model: any, ctx: any) {
   switch (model.model.type) {
     case 'datasource':
       return new variable(model.model, ctx.datasourceSrv, ctx.variableSrv, ctx.templateSrv);

+ 12 - 1
public/app/features/templating/variable.ts

@@ -24,7 +24,18 @@ export interface Variable {
   getSaveModel(): any;
 }
 
-export let variableTypes = {};
+export type CtorType = new (...args: any[]) => {};
+
+export interface VariableTypes {
+  [key: string]: {
+    name: string;
+    ctor: CtorType;
+    description: string;
+    supportsMulti?: boolean;
+  };
+}
+
+export let variableTypes: VariableTypes = {};
 export { assignModelProperties };
 
 export function containsVariable(...args: any[]) {

+ 4 - 4
public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts

@@ -105,7 +105,7 @@ describe('CloudWatchDatasource', () => {
             },
             multi: false,
           },
-          {}
+          {} as any
         ),
       ]);
 
@@ -279,7 +279,7 @@ describe('CloudWatchDatasource', () => {
             },
             multi: false,
           },
-          {}
+          {} as any
         ),
         new CustomVariable(
           {
@@ -289,7 +289,7 @@ describe('CloudWatchDatasource', () => {
             },
             multi: false,
           },
-          {}
+          {} as any
         ),
         new CustomVariable(
           {
@@ -304,7 +304,7 @@ describe('CloudWatchDatasource', () => {
             },
             multi: true,
           },
-          {}
+          {} as any
         ),
       ]);
 

+ 1 - 1
public/app/plugins/datasource/mssql/specs/datasource.test.ts

@@ -236,7 +236,7 @@ describe('MSSQLDatasource', () => {
 
   describe('When interpolating variables', () => {
     beforeEach(() => {
-      ctx.variable = new CustomVariable({}, {});
+      ctx.variable = new CustomVariable({}, {} as any);
     });
 
     describe('and value is a string', () => {

+ 1 - 1
public/app/plugins/datasource/mysql/specs/datasource.test.ts

@@ -198,7 +198,7 @@ describe('MySQLDatasource', () => {
 
   describe('When interpolating variables', () => {
     beforeEach(() => {
-      ctx.variable = new CustomVariable({}, {});
+      ctx.variable = new CustomVariable({}, {} as any);
     });
 
     describe('and value is a string', () => {

+ 1 - 1
public/app/plugins/datasource/postgres/specs/datasource.test.ts

@@ -206,7 +206,7 @@ describe('PostgreSQLDatasource', () => {
 
   describe('When interpolating variables', () => {
     beforeEach(() => {
-      ctx.variable = new CustomVariable({}, {});
+      ctx.variable = new CustomVariable({}, {} as any);
     });
 
     describe('and value is a string', () => {

+ 1 - 1
public/app/plugins/datasource/prometheus/datasource.ts

@@ -349,7 +349,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
 
     // Apply adhoc filters
     const adhocFilters = this.templateSrv.getAdhocFilters(this.name);
-    expr = adhocFilters.reduce((acc, filter) => {
+    expr = adhocFilters.reduce((acc: string, filter: { key?: any; operator?: any; value?: any }) => {
       const { key, operator } = filter;
       let { value } = filter;
       if (operator === '=~' || operator === '!~') {

+ 1 - 1
public/app/plugins/datasource/prometheus/specs/datasource.test.ts

@@ -326,7 +326,7 @@ describe('PrometheusDatasource', () => {
   describe('When interpolating variables', () => {
     beforeEach(() => {
       ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock);
-      ctx.variable = new CustomVariable({}, {});
+      ctx.variable = new CustomVariable({}, {} as any);
     });
 
     describe('and value is a string', () => {

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

@@ -289,7 +289,7 @@ function initTemplateSrv(values: any, multi = false) {
         },
         multi: multi,
       },
-      {}
+      {} as any
     ),
   ]);
   return templateSrv;