Преглед изворни кода

strictNullChecks: First batch (#18390)

* First batch of strictNullChecks

* Remove undefined

* Check an alternative solution

* Fix strict nullChecks

* Low hanging strictNullChecks

* Fixing strict nulls issues and more

* Minor change

* fixed unit test

* Fix feedback

* Update public/vendor/ansicolor/ansicolor.ts

Co-Authored-By: Dominik Prokop <dominik.prokop@grafana.com>

* Update public/vendor/ansicolor/ansicolor.ts

Co-Authored-By: Dominik Prokop <dominik.prokop@grafana.com>

* Update public/vendor/ansicolor/ansicolor.ts

Co-Authored-By: Dominik Prokop <dominik.prokop@grafana.com>

* Fix build errors
Tobias Skarhed пре 6 година
родитељ
комит
1db9fff056
26 измењених фајлова са 143 додато и 160 уклоњено
  1. 3 5
      packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx
  2. 17 24
      packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx
  3. 7 26
      packages/grafana-ui/src/components/ThresholdsEditor/__snapshots__/ThresholdsEditor.test.tsx.snap
  4. 1 1
      packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx
  5. 55 46
      public/app/core/table_model.ts
  6. 1 1
      public/app/core/utils/flatten.ts
  7. 1 1
      public/app/features/panel/panellinks/link_srv.ts
  8. 12 11
      public/app/plugins/datasource/prometheus/specs/query_hints.test.ts
  9. 1 1
      public/app/plugins/datasource/stackdriver/specs/query_filter_ctrl.test.ts
  10. 2 2
      public/app/plugins/panel/graph/GraphContextMenuCtrl.ts
  11. 3 3
      public/app/plugins/panel/graph/Legend/LegendSeriesItem.tsx
  12. 9 7
      public/app/plugins/panel/graph/graph.ts
  13. 1 1
      public/app/plugins/panel/graph/threshold_manager.ts
  14. 1 1
      public/app/plugins/panel/heatmap/rendering.ts
  15. 3 2
      public/app/plugins/panel/singlestat/module.ts
  16. 4 9
      public/app/plugins/panel/singlestat2/ColoringEditor.tsx
  17. 1 1
      public/app/plugins/panel/table/renderer.ts
  18. 1 2
      public/app/plugins/panel/table/specs/transformers.test.ts
  19. 2 2
      public/app/plugins/panel/table/transformers.ts
  20. 0 1
      public/app/plugins/panel/table2/types.ts
  21. 2 2
      public/app/plugins/panel/text2/TextPanelEditor.tsx
  22. 1 1
      public/app/routes/GrafanaCtrl.ts
  23. 3 3
      public/test/core/redux/reducerTester.ts
  24. 6 2
      public/test/mocks/common.ts
  25. 5 5
      public/vendor/ansicolor/ansicolor.ts
  26. 1 0
      tsconfig.json

+ 3 - 5
packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx

@@ -27,7 +27,6 @@ function getCurrentThresholds(editor: ThresholdsEditor) {
 describe('Render', () => {
   it('should render with base threshold', () => {
     const { wrapper } = setup();
-
     expect(wrapper).toMatchSnapshot();
   });
 });
@@ -35,8 +34,7 @@ describe('Render', () => {
 describe('Initialization', () => {
   it('should add a base threshold if missing', () => {
     const { instance } = setup();
-
-    expect(getCurrentThresholds(instance)).toEqual([{ value: -Infinity, color: colors[0] }]);
+    expect(getCurrentThresholds(instance)).toEqual([{ value: -Infinity, color: 'green' }]);
   });
 });
 
@@ -47,8 +45,8 @@ describe('Add threshold', () => {
     instance.onAddThresholdAfter(instance.state.thresholds[0]);
 
     expect(getCurrentThresholds(instance)).toEqual([
-      { value: -Infinity, color: colors[0] }, // 0
-      { value: 50, color: colors[2] }, // 1
+      { value: -Infinity, color: 'green' }, // 0
+      { value: 50, color: colors[1] }, // 1
     ]);
   });
 

+ 17 - 24
packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx

@@ -8,7 +8,7 @@ import { ColorPicker } from '../ColorPicker/ColorPicker';
 import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
 
 export interface Props {
-  thresholds: Threshold[];
+  thresholds?: Threshold[];
   onChange: (thresholds: Threshold[]) => void;
 }
 
@@ -22,35 +22,28 @@ interface ThresholdWithKey extends Threshold {
 
 let counter = 100;
 
+function toThresholdsWithKey(thresholds?: Threshold[]): ThresholdWithKey[] {
+  if (!thresholds || thresholds.length === 0) {
+    thresholds = [{ value: -Infinity, color: 'green' }];
+  }
+
+  return thresholds.map(t => {
+    return {
+      color: t.color,
+      value: t.value === null ? -Infinity : t.value,
+      key: counter++,
+    };
+  });
+}
+
 export class ThresholdsEditor extends PureComponent<Props, State> {
   constructor(props: Props) {
     super(props);
 
-    const thresholds = props.thresholds
-      ? props.thresholds.map(t => {
-          return {
-            color: t.color,
-            value: t.value === null ? -Infinity : t.value,
-            key: counter++,
-          };
-        })
-      : ([] as ThresholdWithKey[]);
-
-    let needsCallback = false;
-    if (!thresholds.length) {
-      thresholds.push({ value: -Infinity, color: colors[0], key: counter++ });
-      needsCallback = true;
-    } else {
-      // First value is always base
-      thresholds[0].value = -Infinity;
-    }
+    const thresholds = toThresholdsWithKey(props.thresholds);
+    thresholds[0].value = -Infinity;
 
-    // Update the state
     this.state = { thresholds };
-
-    if (needsCallback) {
-      this.onChange();
-    }
   }
 
   onAddThresholdAfter = (threshold: ThresholdWithKey) => {

+ 7 - 26
packages/grafana-ui/src/components/ThresholdsEditor/__snapshots__/ThresholdsEditor.test.tsx.snap

@@ -2,26 +2,7 @@
 
 exports[`Render should render with base threshold 1`] = `
 <ThresholdsEditor
-  onChange={
-    [MockFunction] {
-      "calls": Array [
-        Array [
-          Array [
-            Object {
-              "color": "#7EB26D",
-              "value": -Infinity,
-            },
-          ],
-        ],
-      ],
-      "results": Array [
-        Object {
-          "type": "return",
-          "value": undefined,
-        },
-      ],
-    }
-  }
+  onChange={[MockFunction]}
   thresholds={Array []}
 >
   <Component
@@ -61,7 +42,7 @@ exports[`Render should render with base threshold 1`] = `
               className="thresholds-row-color-indicator"
               style={
                 Object {
-                  "backgroundColor": "#7EB26D",
+                  "backgroundColor": "#73BF69",
                 }
               }
             />
@@ -81,12 +62,12 @@ exports[`Render should render with base threshold 1`] = `
                     className="thresholds-row-input-inner-color-colorpicker"
                   >
                     <WithTheme(ColorPicker)
-                      color="#7EB26D"
+                      color="green"
                       enableNamedColors={true}
                       onChange={[Function]}
                     >
                       <ColorPicker
-                        color="#7EB26D"
+                        color="green"
                         enableNamedColors={true}
                         onChange={[Function]}
                         theme={
@@ -247,7 +228,7 @@ exports[`Render should render with base threshold 1`] = `
                         <PopperController
                           content={
                             <ColorPickerPopover
-                              color="#7EB26D"
+                              color="green"
                               enableNamedColors={true}
                               onChange={[Function]}
                               theme={
@@ -409,7 +390,7 @@ exports[`Render should render with base threshold 1`] = `
                           hideAfter={300}
                         >
                           <ForwardRef(ColorPickerTrigger)
-                            color="#7EB26D"
+                            color="#73BF69"
                             onClick={[Function]}
                             onMouseLeave={[Function]}
                           >
@@ -445,7 +426,7 @@ exports[`Render should render with base threshold 1`] = `
                                 <div
                                   style={
                                     Object {
-                                      "backgroundColor": "#7EB26D",
+                                      "backgroundColor": "#73BF69",
                                       "bottom": 0,
                                       "display": "block",
                                       "left": 0,

+ 1 - 1
packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx

@@ -5,7 +5,7 @@ import { MappingType, ValueMapping } from '@grafana/data';
 import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
 
 export interface Props {
-  valueMappings: ValueMapping[];
+  valueMappings?: ValueMapping[];
   onChange: (valueMappings: ValueMapping[]) => void;
 }
 

+ 55 - 46
public/app/core/table_model.ts

@@ -103,16 +103,19 @@ export function mergeTablesIntoModel(dst?: TableModel, ...tables: TableModel[]):
   const columnNames: { [key: string]: any } = {};
 
   // Union of all non-value columns
-  const columnsUnion = tables.slice().reduce((acc, series) => {
-    series.columns.forEach(col => {
-      const { text } = col;
-      if (columnNames[text] === undefined) {
-        columnNames[text] = acc.length;
-        acc.push(col);
-      }
-    });
-    return acc;
-  }, []);
+  const columnsUnion = tables.slice().reduce(
+    (acc, series) => {
+      series.columns.forEach(col => {
+        const { text } = col;
+        if (columnNames[text] === undefined) {
+          columnNames[text] = acc.length;
+          acc.push(col);
+        }
+      });
+      return acc;
+    },
+    [] as MutableColumn[]
+  );
 
   // Map old column index to union index per series, e.g.,
   // given columnNames {A: 0, B: 1} and
@@ -120,51 +123,57 @@ export function mergeTablesIntoModel(dst?: TableModel, ...tables: TableModel[]):
   const columnIndexMapper = tables.map(series => series.columns.map(col => columnNames[col.text]));
 
   // Flatten rows of all series and adjust new column indexes
-  const flattenedRows = tables.reduce((acc, series, seriesIndex) => {
-    const mapper = columnIndexMapper[seriesIndex];
-    series.rows.forEach(row => {
-      const alteredRow: any[] = [];
-      // Shifting entries according to index mapper
-      mapper.forEach((to, from) => {
-        alteredRow[to] = row[from];
+  const flattenedRows = tables.reduce(
+    (acc, series, seriesIndex) => {
+      const mapper = columnIndexMapper[seriesIndex];
+      series.rows.forEach(row => {
+        const alteredRow: MutableColumn[] = [];
+        // Shifting entries according to index mapper
+        mapper.forEach((to, from) => {
+          alteredRow[to] = row[from];
+        });
+        acc.push(alteredRow);
       });
-      acc.push(alteredRow);
-    });
-    return acc;
-  }, []);
+      return acc;
+    },
+    [] as MutableColumn[][]
+  );
 
   // Merge rows that have same values for columns
   const mergedRows: { [key: string]: any } = {};
 
-  const compactedRows = flattenedRows.reduce((acc, row, rowIndex) => {
-    if (!mergedRows[rowIndex]) {
-      // Look from current row onwards
-      let offset = rowIndex + 1;
-      // More than one row can be merged into current row
-      while (offset < flattenedRows.length) {
-        // Find next row that could be merged
-        const match = _.findIndex(flattenedRows, otherRow => areRowsMatching(columnsUnion, row, otherRow), offset);
-        if (match > -1) {
-          const matchedRow = flattenedRows[match];
-          // Merge values from match into current row if there is a gap in the current row
-          for (let columnIndex = 0; columnIndex < columnsUnion.length; columnIndex++) {
-            if (row[columnIndex] === undefined && matchedRow[columnIndex] !== undefined) {
-              row[columnIndex] = matchedRow[columnIndex];
+  const compactedRows = flattenedRows.reduce(
+    (acc, row, rowIndex) => {
+      if (!mergedRows[rowIndex]) {
+        // Look from current row onwards
+        let offset = rowIndex + 1;
+        // More than one row can be merged into current row
+        while (offset < flattenedRows.length) {
+          // Find next row that could be merged
+          const match = _.findIndex(flattenedRows, otherRow => areRowsMatching(columnsUnion, row, otherRow), offset);
+          if (match > -1) {
+            const matchedRow = flattenedRows[match];
+            // Merge values from match into current row if there is a gap in the current row
+            for (let columnIndex = 0; columnIndex < columnsUnion.length; columnIndex++) {
+              if (row[columnIndex] === undefined && matchedRow[columnIndex] !== undefined) {
+                row[columnIndex] = matchedRow[columnIndex];
+              }
             }
+            // Don't visit this row again
+            mergedRows[match] = matchedRow;
+            // Keep looking for more rows to merge
+            offset = match + 1;
+          } else {
+            // No match found, stop looking
+            break;
           }
-          // Don't visit this row again
-          mergedRows[match] = matchedRow;
-          // Keep looking for more rows to merge
-          offset = match + 1;
-        } else {
-          // No match found, stop looking
-          break;
         }
+        acc.push(row);
       }
-      acc.push(row);
-    }
-    return acc;
-  }, []);
+      return acc;
+    },
+    [] as MutableColumn[][]
+  );
 
   model.columns = columnsUnion;
   model.rows = compactedRows;

+ 1 - 1
public/app/core/utils/flatten.ts

@@ -1,7 +1,7 @@
 // Copyright (c) 2014, Hugh Kennedy
 // Based on code from https://github.com/hughsk/flat/blob/master/index.js
 //
-export default function flatten(target: object, opts: { delimiter?: any; maxDepth?: any; safe?: any }): any {
+export default function flatten(target: object, opts?: { delimiter?: any; maxDepth?: any; safe?: any }): any {
   opts = opts || {};
 
   const delimiter = opts.delimiter || '.';

+ 1 - 1
public/app/features/panel/panellinks/link_srv.ts

@@ -46,7 +46,7 @@ export const getDataLinksVariableSuggestions = (): VariableSuggestion[] => [
 
 type LinkTarget = '_blank' | '_self';
 
-interface LinkModel {
+export interface LinkModel {
   href: string;
   title: string;
   target: LinkTarget;

+ 12 - 11
public/app/plugins/datasource/prometheus/specs/query_hints.test.ts

@@ -24,8 +24,9 @@ describe('getQueryHints()', () => {
   it('returns a rate hint for a monotonically increasing series', () => {
     const series = [{ datapoints: [[23, 1000], [24, 1001]] }];
     const hints = getQueryHints('metric', series);
-    expect(hints.length).toBe(1);
-    expect(hints[0]).toMatchObject({
+
+    expect(hints!.length).toBe(1);
+    expect(hints![0]).toMatchObject({
       label: 'Time series is monotonically increasing.',
       fix: {
         action: {
@@ -45,16 +46,16 @@ describe('getQueryHints()', () => {
   it('returns a rate hint w/o action for a complex monotonically increasing series', () => {
     const series = [{ datapoints: [[23, 1000], [24, 1001]] }];
     const hints = getQueryHints('sum(metric)', series);
-    expect(hints.length).toBe(1);
-    expect(hints[0].label).toContain('rate()');
-    expect(hints[0].fix).toBeUndefined();
+    expect(hints!.length).toBe(1);
+    expect(hints![0].label).toContain('rate()');
+    expect(hints![0].fix).toBeUndefined();
   });
 
   it('returns a rate hint for a monotonically increasing series with missing data', () => {
     const series = [{ datapoints: [[23, 1000], [null, 1001], [24, 1002]] }];
     const hints = getQueryHints('metric', series);
-    expect(hints.length).toBe(1);
-    expect(hints[0]).toMatchObject({
+    expect(hints!.length).toBe(1);
+    expect(hints![0]).toMatchObject({
       label: 'Time series is monotonically increasing.',
       fix: {
         action: {
@@ -68,8 +69,8 @@ describe('getQueryHints()', () => {
   it('returns a histogram hint for a bucket series', () => {
     const series = [{ datapoints: [[23, 1000]] }];
     const hints = getQueryHints('metric_bucket', series);
-    expect(hints.length).toBe(1);
-    expect(hints[0]).toMatchObject({
+    expect(hints!.length).toBe(1);
+    expect(hints![0]).toMatchObject({
       label: 'Time series has buckets, you probably wanted a histogram.',
       fix: {
         action: {
@@ -86,8 +87,8 @@ describe('getQueryHints()', () => {
       datapoints: [[0, 0], [0, 0]],
     }));
     const hints = getQueryHints('metric', series);
-    expect(hints.length).toBe(1);
-    expect(hints[0]).toMatchObject({
+    expect(hints!.length).toBe(1);
+    expect(hints![0]).toMatchObject({
       type: 'ADD_SUM',
       label: 'Many time series results returned.',
       fix: {

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

@@ -3,7 +3,7 @@ import { TemplateSrvStub } from 'test/specs/helpers';
 import { DefaultRemoveFilterValue, DefaultFilterValue } from '../filter_segments';
 
 describe('StackdriverQueryFilterCtrl', () => {
-  let ctrl: Partial<StackdriverFilterCtrl>;
+  let ctrl: StackdriverFilterCtrl;
   let result: any;
   let groupByChangedMock: any;
 

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

@@ -13,7 +13,7 @@ export class GraphContextMenuCtrl {
   private source?: FlotDataPoint | null;
   private scope?: any;
   menuItems: ContextMenuItem[];
-  scrollContextElement: HTMLElement;
+  scrollContextElement: HTMLElement | null;
   position: {
     x: number;
     y: number;
@@ -58,7 +58,7 @@ export class GraphContextMenuCtrl {
 
   // Sets element which is considered as a scroll context of given context menu.
   // Having access to this element allows scroll event attachement for menu to be closed when user scrolls
-  setScrollContextElement = (el: HTMLElement) => {
+  setScrollContextElement = (el: HTMLElement | null) => {
     this.scrollContextElement = el;
   };
 

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

@@ -9,9 +9,9 @@ export interface LegendLabelProps {
   series: TimeSeries;
   asTable?: boolean;
   hidden?: boolean;
-  onLabelClick?: (series: any, event: any) => void;
-  onColorChange?: (series: any, color: string) => void;
-  onToggleAxis?: (series: any) => void;
+  onLabelClick: (series: any, event: any) => void;
+  onColorChange: (series: any, color: string) => void;
+  onToggleAxis: (series: any) => void;
 }
 
 export interface LegendValuesProps {

+ 9 - 7
public/app/plugins/panel/graph/graph.ts

@@ -135,9 +135,6 @@ class GraphElement {
   }
 
   onPanelTeardown() {
-    this.thresholdManager = null;
-    this.timeRegionManager = null;
-
     if (this.plot) {
       this.plot.destroy();
       this.plot = null;
@@ -587,19 +584,24 @@ class GraphElement {
   }
 
   addXHistogramAxis(options: any, bucketSize: number) {
-    let ticks, min, max;
+    let ticks: number | number[];
+    let min: number | undefined;
+    let max: number | undefined;
+
     const defaultTicks = this.panelWidth / 50;
 
     if (this.data.length && bucketSize) {
       const tickValues = [];
+
       for (const d of this.data) {
         for (const point of d.data) {
           tickValues[point[0]] = true;
         }
       }
+
       ticks = Object.keys(tickValues).map(v => Number(v));
-      min = _.min(ticks);
-      max = _.max(ticks);
+      min = _.min(ticks)!;
+      max = _.max(ticks)!;
 
       // Adjust tick step
       let tickStep = bucketSize;
@@ -819,7 +821,7 @@ class GraphElement {
     };
   }
 
-  time_format(ticks: number, min: number, max: number) {
+  time_format(ticks: number, min: number | null, max: number | null) {
     if (min && max && ticks) {
       const range = max - min;
       const secPerTick = range / ticks / 1000;

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

@@ -35,7 +35,7 @@ export class ThresholdManager {
     const handleElem = $(evt.currentTarget).parents('.alert-handle-wrapper');
     const handleIndex = $(evt.currentTarget).data('handleIndex');
 
-    let lastY: number = null;
+    let lastY: number | null = null;
     let posTop: number;
     const plot = this.plot;
     const panelCtrl = this.panelCtrl;

+ 1 - 1
public/app/plugins/panel/heatmap/rendering.ts

@@ -520,7 +520,7 @@ export class HeatmapRenderer {
       const logBase = this.panel.yAxis.logBase;
       const domain = this.yScale.domain();
       const tickValues = this.logScaleTickValues(domain, logBase);
-      this.data.buckets = mergeZeroBuckets(this.data.buckets, _.min(tickValues));
+      this.data.buckets = mergeZeroBuckets(this.data.buckets, _.min(tickValues)!);
     }
 
     const cardsData = this.data.cards;

+ 3 - 2
public/app/plugins/panel/singlestat/module.ts

@@ -12,7 +12,7 @@ import { MetricsPanelCtrl } from 'app/plugins/sdk';
 import { isTableData } from '@grafana/data';
 import { GrafanaThemeType, getValueFormat, getColorFromHexRgbOrName } from '@grafana/ui';
 import { auto } from 'angular';
-import { LinkSrv } from 'app/features/panel/panellinks/link_srv';
+import { LinkSrv, LinkModel } from 'app/features/panel/panellinks/link_srv';
 import TableModel from 'app/core/table_model';
 
 const BASE_FONT_SIZE = 38;
@@ -385,7 +385,8 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     const $sanitize = this.$sanitize;
     const panel = ctrl.panel;
     const templateSrv = this.templateSrv;
-    let data: any, linkInfo: { target: string; href: string; title: string };
+    let data: any;
+    let linkInfo: LinkModel | null = null;
     const $panelContainer = elem.find('.panel-container');
     elem = elem.find('.singlestat-panel');
 

+ 4 - 9
public/app/plugins/panel/singlestat2/ColoringEditor.tsx

@@ -14,11 +14,6 @@ export interface Props {
   onChange: (options: SingleStatOptions) => void;
 }
 
-// colorBackground?: boolean;
-// colorValue?: boolean;
-// colorPrefix?: boolean;
-// colorPostfix?: boolean;
-
 export class ColoringEditor extends PureComponent<Props> {
   onToggleColorBackground = () =>
     this.props.onChange({ ...this.props.options, colorBackground: !this.props.options.colorBackground });
@@ -39,27 +34,27 @@ export class ColoringEditor extends PureComponent<Props> {
         <Switch
           label="Background"
           labelClass={`width-${labelWidth}`}
-          checked={colorBackground}
+          checked={colorBackground!}
           onChange={this.onToggleColorBackground}
         />
 
         <Switch
           label="Value"
           labelClass={`width-${labelWidth}`}
-          checked={colorValue}
+          checked={colorValue!}
           onChange={this.onToggleColorValue}
         />
 
         <Switch
           label="Prefix"
           labelClass={`width-${labelWidth}`}
-          checked={colorPrefix}
+          checked={colorPrefix!}
           onChange={this.onToggleColorPrefix}
         />
         <Switch
           label="Postfix"
           labelClass={`width-${labelWidth}`}
-          checked={colorPostfix}
+          checked={colorPostfix!}
           onChange={this.onToggleColorPostfix}
         />
       </PanelOptionsGroup>

+ 1 - 1
public/app/plugins/panel/table/renderer.ts

@@ -55,7 +55,7 @@ export class TableRenderer {
   }
 
   getColorForValue(value: number, style: ColumnStyle) {
-    if (!style.thresholds) {
+    if (!style.thresholds || !style.colors) {
       return null;
     }
     for (let i = style.thresholds.length; i > 0; i--) {

+ 1 - 2
public/app/plugins/panel/table/specs/transformers.test.ts

@@ -1,8 +1,7 @@
 import { transformers, transformDataToTable } from '../transformers';
-import { TableData } from '@grafana/data';
 
 describe('when transforming time series table', () => {
-  let table: TableData;
+  let table: any;
 
   describe('given 2 time series', () => {
     const time = new Date().getTime();

+ 2 - 2
public/app/plugins/panel/table/transformers.ts

@@ -191,7 +191,7 @@ transformers['json'] = {
       const maxDocs = Math.min(series.datapoints.length, 100);
       for (let y = 0; y < maxDocs; y++) {
         const doc = series.datapoints[y];
-        const flattened = flatten(doc, null);
+        const flattened = flatten(doc, {});
         for (const propName in flattened) {
           names[propName] = true;
         }
@@ -228,7 +228,7 @@ transformers['json'] = {
         const values = [];
 
         if (_.isObject(dp) && panel.columns.length > 0) {
-          const flattened = flatten(dp, null);
+          const flattened = flatten(dp);
           for (z = 0; z < panel.columns.length; z++) {
             values.push(flattened[panel.columns[z].value]);
           }

+ 0 - 1
public/app/plugins/panel/table2/types.ts

@@ -27,7 +27,6 @@ export const defaults: Options = {
       alias: '',
       decimals: 2,
       colors: ['rgba(245, 54, 54, 0.9)', 'rgba(237, 129, 40, 0.89)', 'rgba(50, 172, 45, 0.97)'],
-      colorMode: null,
       pattern: '/.*/',
       thresholds: [],
     },

+ 2 - 2
public/app/plugins/panel/text2/TextPanelEditor.tsx

@@ -16,10 +16,10 @@ export class TextPanelEditor extends PureComponent<PanelEditorProps<TextOptions>
   ];
 
   onModeChange = (item: SelectableValue<TextMode>) =>
-    this.props.onOptionsChange({ ...this.props.options, mode: item.value });
+    this.props.onOptionsChange({ ...this.props.options, mode: item.value! });
 
   onContentChange = (evt: ChangeEvent<HTMLTextAreaElement>) => {
-    this.props.onOptionsChange({ ...this.props.options, content: (event.target as any).value });
+    this.props.onOptionsChange({ ...this.props.options, content: (evt.target as any).value });
   };
 
   render() {

+ 1 - 1
public/app/routes/GrafanaCtrl.ts

@@ -206,7 +206,7 @@ export function grafanaAppDirective(
         }
 
         $timeout(() => $location.search(search));
-        setViewModeBodyClass(body, search.kiosk);
+        setViewModeBodyClass(body, search.kiosk!);
       });
 
       // handle in active view state class

+ 3 - 3
public/test/core/redux/reducerTester.ts

@@ -49,9 +49,9 @@ const deepFreeze = <T>(obj: T): T => {
 interface ReducerTester<State> extends Given<State>, When<State>, Then<State> {}
 
 export const reducerTester = <State>(): Given<State> => {
-  let reducerUnderTest: Reducer<State, ActionOf<any>> = null;
-  let resultingState: State = null;
-  let initialState: State = null;
+  let reducerUnderTest: Reducer<State, ActionOf<any>>;
+  let resultingState: State;
+  let initialState: State;
 
   const givenReducer = (reducer: Reducer<State, ActionOf<any>>, state: State): When<State> => {
     reducerUnderTest = reducer;

+ 6 - 2
public/test/mocks/common.ts

@@ -31,8 +31,10 @@ export function createNavModel(title: string, ...tabs: string[]): NavModel {
     breadcrumbs: [],
   };
 
+  const children = [];
+
   for (const tab of tabs) {
-    node.children.push({
+    children.push({
       id: tab,
       icon: 'icon',
       subTitle: 'subTitle',
@@ -42,7 +44,9 @@ export function createNavModel(title: string, ...tabs: string[]): NavModel {
     });
   }
 
-  node.children[0].active = true;
+  children[0].active = true;
+
+  node.children = children;
 
   return {
     node: node,

+ 5 - 5
public/vendor/ansicolor/ansicolor.ts

@@ -60,9 +60,9 @@ const clean = (obj: any) => {
 /*  ------------------------------------------------------------------------ */
 
 class Color {
-  background: boolean;
-  name: string;
-  brightness: number;
+  background?: boolean;
+  name?: string;
+  brightness?: number;
 
   constructor(background?: boolean, name?: string, brightness?: number) {
     this.background = background;
@@ -82,7 +82,7 @@ class Color {
     });
   }
 
-  defaultBrightness(value: number) {
+  defaultBrightness(value?: number) {
     return new Color(this.background, this.name, this.brightness || value);
   }
 
@@ -351,7 +351,7 @@ export default class Colors {
 
   get parsed() {
     let styles: Set<string>;
-    let brightness: number;
+    let brightness: number | undefined;
     let color: Color;
     let bgColor: Color;
 

+ 1 - 0
tsconfig.json

@@ -19,6 +19,7 @@
     "noEmitOnError": false,
     "emitDecoratorMetadata": false,
     "experimentalDecorators": true,
+    "strictNullChecks": false,
     "noImplicitReturns": true,
     "noImplicitThis": true,
     "noImplicitUseStrict": false,