diff --git a/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingColumns.jsx b/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingColumns.jsx
index 0b798bfa10468f3a3306f1a384a93ba5008629b5..9034001f4bf6a0cbf98e5464c89f59f76f77bc23 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingColumns.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartNestedSettingColumns.jsx
@@ -1,3 +1,5 @@
+/* @flow */
+
 import React from "react";
 
 import Icon from "metabase/components/Icon";
@@ -7,8 +9,12 @@ import ColumnItem from "./ColumnItem";
 const displayNameForColumn = column =>
   column ? column.display_name || column.name : "[Unknown]";
 
+import type { NestedSettingComponentProps } from "./ChartSettingNestedSettings";
+
 // various props injected by chartSettingNestedSettings HOC
 export default class ChartNestedSettingSeries extends React.Component {
+  props: NestedSettingComponentProps;
+
   render() {
     const {
       objects,
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingNestedSettings.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingNestedSettings.jsx
index 4b964efc5184443c53b8bb52cd701f783c704386..f45dd92c53da8c2b886303875892c8537dc7b398 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingNestedSettings.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingNestedSettings.jsx
@@ -1,15 +1,66 @@
+/* @flow */
+
 import React from "react";
 
 import ChartSettingsWidget from "../ChartSettingsWidget";
 
 import _ from "underscore";
 
+import type {
+  Settings,
+  ExtraProps,
+  WidgetDef,
+} from "metabase/visualizations/lib/settings";
+import type {
+  NestedObject,
+  NestedObjectKey,
+  SettingsWidgetsForObjectGetter,
+  NestedObjectKeyGetter,
+} from "metabase/visualizations/lib/settings/nested";
+import type { Series } from "metabase/meta/types/Visualization";
+
+export type NestedSettingComponentProps = {
+  objects: NestedObject[],
+  object: ?NestedObject,
+  objectSettingsWidgets: ?(WidgetDef[]),
+  onChangeEditingObject: (editingObject: ?NestedObject) => void,
+};
+type NestedSettingComponent = Class<
+  React$Component<NestedSettingComponentProps, *, *>,
+>;
+
+type SettingsByObjectKey = { [key: NestedObjectKey]: Settings };
+
+type Props = {
+  value: SettingsByObjectKey,
+  onChange: (newSettings: SettingsByObjectKey) => void,
+  onEndEditing?: () => void,
+  series: Series,
+  extra: ExtraProps,
+  objects: NestedObject[],
+  initialKey?: NestedObjectKey,
+};
+
+type State = {
+  editingObjectKey: ?NestedObjectKey,
+};
+
+type ChartSettingsNestedSettingHOCProps = {
+  getObjectKey: NestedObjectKeyGetter,
+  getSettingsWidgetsForObject: SettingsWidgetsForObjectGetter,
+};
+
 const chartSettingNestedSettings = ({
   getObjectKey,
   getSettingsWidgetsForObject,
-}) => ComposedComponent =>
+}: ChartSettingsNestedSettingHOCProps) => (
+  ComposedComponent: NestedSettingComponent,
+) =>
   class extends React.Component {
-    constructor(props) {
+    props: Props;
+    state: State;
+
+    constructor(props: Props) {
       super(props);
       this.state = {
         editingObjectKey:
@@ -18,7 +69,7 @@ const chartSettingNestedSettings = ({
       };
     }
 
-    componentWillReceiveProps(nextProps) {
+    componentWillReceiveProps(nextProps: Props) {
       // reset editingObjectKey if there's only one object
       if (
         nextProps.objects.length === 1 &&
@@ -30,7 +81,7 @@ const chartSettingNestedSettings = ({
       }
     }
 
-    handleChangeEditingObject = editingObject => {
+    handleChangeEditingObject = (editingObject: ?NestedObject) => {
       this.setState({
         editingObjectKey: editingObject ? getObjectKey(editingObject) : null,
       });
@@ -40,16 +91,27 @@ const chartSettingNestedSettings = ({
       }
     };
 
-    handleChangeSettingsForEditingObject = newSettings => {
+    handleChangeSettingsForEditingObject = (newSettings: Settings) => {
       const { editingObjectKey } = this.state;
-      this.handleChangeSettingsForObjectKey(editingObjectKey, newSettings);
+      if (editingObjectKey) {
+        this.handleChangeSettingsForObjectKey(editingObjectKey, newSettings);
+      }
     };
 
-    handleChangeSettingsForObject = (object, newSettings) => {
-      this.handleChangeSettingsForObjectKey(getObjectKey(object), newSettings);
+    handleChangeSettingsForObject = (
+      object: NestedObject,
+      newSettings: Settings,
+    ) => {
+      const objectKey = getObjectKey(object);
+      if (objectKey) {
+        this.handleChangeSettingsForObjectKey(objectKey, newSettings);
+      }
     };
 
-    handleChangeSettingsForObjectKey = (objectKey, newSettings) => {
+    handleChangeSettingsForObjectKey = (
+      objectKey: NestedObjectKey,
+      newSettings: Settings,
+    ) => {
       const { onChange } = this.props;
       const objectsSettings = this.props.value || {};
       const objectSettings = objectsSettings[objectKey] || {};
@@ -65,43 +127,44 @@ const chartSettingNestedSettings = ({
     render() {
       const { series, objects, extra } = this.props;
       const { editingObjectKey } = this.state;
-      const objectsSettings = this.props.value || {};
 
-      const editingObject = _.find(
-        objects,
-        o => getObjectKey(o) === editingObjectKey,
-      );
-      if (editingObject) {
-        const objectSettings = objectsSettings[editingObjectKey] || {};
-        const objectSettingsWidgets = getSettingsWidgetsForObject(
-          series,
-          editingObject,
-          objectSettings,
-          this.handleChangeSettingsForEditingObject,
-          extra,
-        );
-        return (
-          <ComposedComponent
-            {...this.props}
-            getObjectKey={getObjectKey}
-            onChangeEditingObject={this.handleChangeEditingObject}
-            onChangeObjectSettings={this.handleChangeSettingsForObject}
-            object={editingObject}
-            objectSettingsWidgets={objectSettingsWidgets.map(widget => (
-              <ChartSettingsWidget key={widget.id} {...widget} />
-            ))}
-          />
-        );
-      } else {
-        return (
-          <ComposedComponent
-            {...this.props}
-            getObjectKey={getObjectKey}
-            onChangeEditingObject={this.handleChangeEditingObject}
-            onChangeObjectSettings={this.handleChangeSettingsForObject}
-          />
+      if (editingObjectKey) {
+        const editingObject = _.find(
+          objects,
+          o => getObjectKey(o) === editingObjectKey,
         );
+        if (editingObject) {
+          const objectsSettings = this.props.value || {};
+          const objectSettings = objectsSettings[editingObjectKey] || {};
+          const objectSettingsWidgets = getSettingsWidgetsForObject(
+            series,
+            editingObject,
+            objectSettings,
+            this.handleChangeSettingsForEditingObject,
+            extra,
+          );
+          return (
+            <ComposedComponent
+              {...this.props}
+              getObjectKey={getObjectKey}
+              onChangeEditingObject={this.handleChangeEditingObject}
+              onChangeObjectSettings={this.handleChangeSettingsForObject}
+              object={editingObject}
+              objectSettingsWidgets={objectSettingsWidgets.map(widget => (
+                <ChartSettingsWidget key={widget.id} {...widget} />
+              ))}
+            />
+          );
+        }
       }
+      return (
+        <ComposedComponent
+          {...this.props}
+          getObjectKey={getObjectKey}
+          onChangeEditingObject={this.handleChangeEditingObject}
+          onChangeObjectSettings={this.handleChangeSettingsForObject}
+        />
+      );
     }
   };
 
diff --git a/frontend/src/metabase/visualizations/lib/settings.js b/frontend/src/metabase/visualizations/lib/settings.js
index da179387bbdd807c2fff42b1f87084c6f58bdcfd..048d0c28f971973e0711c3f3b5aa3733cc0a0181 100644
--- a/frontend/src/metabase/visualizations/lib/settings.js
+++ b/frontend/src/metabase/visualizations/lib/settings.js
@@ -23,8 +23,6 @@ export type SettingDefs = {
 };
 
 export type SettingDef = {
-  id?: SettingId,
-  value?: any,
   title?: string,
   props?: { [key: string]: any },
   default?: any,
@@ -57,6 +55,8 @@ export type WidgetDef = {
   onChange: (value: any) => void,
 };
 
+export type ExtraProps = { [key: string]: any };
+
 const WIDGETS = {
   input: ChartSettingInput,
   inputGroup: ChartSettingInputGroup,
@@ -75,7 +75,7 @@ export function getComputedSettings(
   settingsDefs: SettingDefs,
   object: any,
   storedSettings: Settings,
-  extra?: { [key: string]: any } = {},
+  extra?: ExtraProps = {},
 ) {
   const computedSettings = {};
   for (let settingId in settingsDefs) {
@@ -97,7 +97,7 @@ function getComputedSetting(
   settingId: SettingId,
   object: any,
   storedSettings: Settings,
-  extra?: { [key: string]: any } = {},
+  extra?: ExtraProps = {},
 ): any {
   if (settingId in computedSettings) {
     return;
@@ -158,7 +158,7 @@ function getSettingWidget(
   settings: Settings,
   object: any,
   onChangeSettings: (settings: Settings) => void,
-  extra?: { [key: string]: any } = {},
+  extra?: ExtraProps = {},
 ): WidgetDef {
   const settingDef = settingDefs[settingId];
   const value = settings[settingId];
@@ -204,7 +204,7 @@ export function getSettingsWidgets(
   settings: Settings,
   object: any,
   onChangeSettings: (settings: Settings) => void,
-  extra?: { [key: string]: any } = {},
+  extra?: ExtraProps = {},
 ) {
   return Object.keys(settingDefs)
     .map(settingId =>
diff --git a/frontend/src/metabase/visualizations/lib/settings/nested.js b/frontend/src/metabase/visualizations/lib/settings/nested.js
index d414bc0dce69c4aad0a028a167b6b3386846ff51..73c9e5360d5fe0d8de4b122b917e0683f32f0bad 100644
--- a/frontend/src/metabase/visualizations/lib/settings/nested.js
+++ b/frontend/src/metabase/visualizations/lib/settings/nested.js
@@ -12,29 +12,42 @@ import type {
   SettingDef,
   SettingDefs,
   Settings,
+  WidgetDef,
+  ExtraProps,
 } from "metabase/visualizations/lib/settings";
 
 import type { Series } from "metabase/meta/types/Visualization";
 
-type Object = any;
+export type NestedObject = any;
+export type NestedObjectKey = string;
 
 type NestedSettingDef = SettingDef & {
   objectName: string,
-  getObjects: (series: Series, settings: Settings) => Object[],
-  getObjectKey: (object: Object) => string,
+  getObjects: (series: Series, settings: Settings) => NestedObject[],
+  getObjectKey: (object: NestedObject) => string,
   getSettingDefintionsForObject: (
     series: Series,
-    object: Object,
+    object: NestedObject,
   ) => SettingDefs,
   getObjectSettingsExtra?: (
     series: Series,
     settings: Settings,
-    object: Object,
+    object: NestedObject,
   ) => { [key: string]: any },
   component: React$Component<any, any, any>,
   id?: SettingId,
 };
 
+export type SettingsWidgetsForObjectGetter = (
+  series: Series,
+  object: NestedObject,
+  storedSettings: Settings,
+  onChangeSettings: (newSettings: Settings) => void,
+  extra: ExtraProps,
+) => WidgetDef[];
+
+export type NestedObjectKeyGetter = (object: NestedObject) => NestedObjectKey;
+
 export function nestedSettings(
   id: SettingId,
   {
@@ -134,7 +147,7 @@ export function nestedSettings(
     [objectName]: {
       getDefault(series: Series, settings: Settings) {
         const cache = new Map();
-        return (object: Object) => {
+        return (object: NestedObject) => {
           const key = getObjectKey(object);
           if (!cache.has(key)) {
             cache.set(key, {
diff --git a/frontend/src/metabase/visualizations/visualizations/Table.jsx b/frontend/src/metabase/visualizations/visualizations/Table.jsx
index dc4869f6078bb51f8686459164ad10b1a2abb779..4922f568fe3bae5b826cd41bd1c5061e0b5abcfe 100644
--- a/frontend/src/metabase/visualizations/visualizations/Table.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Table.jsx
@@ -36,6 +36,7 @@ import { getIn } from "icepick";
 
 import type { DatasetData } from "metabase/meta/types/Dataset";
 import type { Card, VisualizationSettings } from "metabase/meta/types/Card";
+import type { SettingDefs } from "metabase/visualizations/lib/settings";
 
 type Props = {
   card: Card,
@@ -65,7 +66,7 @@ export default class Table extends Component {
     // scalar can always be rendered, nothing needed here
   }
 
-  static settings = {
+  static settings: SettingDefs = {
     ...columnSettings({ hidden: true }),
     "table.pivot": {
       section: t`Columns`,