diff --git a/packages/devui/src/index.ts b/packages/devui/src/index.ts index cf2dfa86..531ce231 100644 --- a/packages/devui/src/index.ts +++ b/packages/devui/src/index.ts @@ -14,3 +14,4 @@ export * from './Toolbar'; import color from './utils/color'; export const effects = { color }; export { default as createStyledComponent } from './utils/createStyledComponent'; +export { Theme, Scheme } from './utils/theme'; diff --git a/packages/devui/src/utils/theme.ts b/packages/devui/src/utils/theme.ts index 5bfd788c..b0180cb7 100644 --- a/packages/devui/src/utils/theme.ts +++ b/packages/devui/src/utils/theme.ts @@ -3,19 +3,22 @@ import { nicinabox as defaultDarkScheme } from 'redux-devtools-themes'; import * as baseSchemes from 'base16'; import * as additionalSchemes from '../colorSchemes'; import invertColors from '../utils/invertColors'; -import { Theme } from '../themes/default'; +import { Theme as ThemeBase } from '../themes/default'; export const schemes = { ...baseSchemes, ...additionalSchemes }; export const listSchemes = () => Object.keys(schemes).slice(1).sort(); // remove `__esModule` export const listThemes = () => Object.keys(themes); +export type Theme = keyof typeof themes; +export type Scheme = keyof typeof schemes; + export interface ThemeData { theme: keyof typeof themes; scheme: keyof typeof schemes; light: boolean; } -export interface ThemeFromProvider extends Theme { +export interface ThemeFromProvider extends ThemeBase { type: keyof typeof themes; light: boolean; } diff --git a/packages/redux-devtools-core/src/app/actions/index.ts b/packages/redux-devtools-core/src/app/actions/index.ts index 9e568444..9a88dec0 100644 --- a/packages/redux-devtools-core/src/app/actions/index.ts +++ b/packages/redux-devtools-core/src/app/actions/index.ts @@ -20,11 +20,29 @@ import { RECONNECT } from '../constants/socketActionTypes'; let monitorReducer; let monitorProps = {}; -export function changeSection(section) { +interface ChangeSectionAction { + readonly type: typeof CHANGE_SECTION; + readonly section: string; +} +export function changeSection(section: string): ChangeSectionAction { return { type: CHANGE_SECTION, section }; } -export function changeTheme(data) { +interface ChangeThemeFormData { + readonly theme: 'default' | 'material'; + readonly scheme: string; + readonly dark: boolean; +} +interface ChangeThemeData { + readonly formData: ChangeThemeFormData; +} +interface ChangeThemeAction { + readonly type: typeof CHANGE_THEME; + readonly theme: 'default' | 'material'; + readonly scheme: string; + readonly dark: boolean; +} +export function changeTheme(data: ChangeThemeData): ChangeThemeAction { return { type: CHANGE_THEME, ...data.formData }; } @@ -63,7 +81,10 @@ export function importState(state, preloadedState) { return { type: LIFTED_ACTION, message: 'IMPORT', state, preloadedState }; } -export function exportState() { +interface ExportAction { + type: typeof EXPORT; +} +export function exportState(): ExportAction { return { type: EXPORT }; } @@ -89,34 +110,81 @@ export function dispatchRemotely(action) { return { type: LIFTED_ACTION, message: 'ACTION', action }; } -export function togglePersist() { +interface TogglePersistAction { + type: typeof TOGGLE_PERSIST; +} +export function togglePersist(): TogglePersistAction { return { type: TOGGLE_PERSIST }; } -export function toggleSync() { +interface ToggleSyncAction { + type: typeof TOGGLE_SYNC; +} +export function toggleSync(): ToggleSyncAction { return { type: TOGGLE_SYNC }; } -export function toggleSlider() { +interface ToggleSliderAction { + type: typeof TOGGLE_SLIDER; +} +export function toggleSlider(): ToggleSliderAction { return { type: TOGGLE_SLIDER }; } -export function toggleDispatcher() { +interface ToggleDispatcherAction { + type: typeof TOGGLE_DISPATCHER; +} +export function toggleDispatcher(): ToggleDispatcherAction { return { type: TOGGLE_DISPATCHER }; } -export function saveSocketSettings(options) { +interface ConnectionOptions { + readonly type: 'disabled' | 'remotedev' | 'custom'; + readonly hostname: string; + readonly port: number; + readonly secure: boolean; +} +interface ReconnectAction { + readonly type: typeof RECONNECT; + readonly options: ConnectionOptions; +} +export function saveSocketSettings( + options: ConnectionOptions +): ReconnectAction { return { type: RECONNECT, options }; } -export function showNotification(message) { +interface Notification { + readonly type: 'error'; + readonly message: string; +} +interface ShowNotificationAction { + readonly type: typeof SHOW_NOTIFICATION; + readonly notification: Notification; +} +export function showNotification(message: string): ShowNotificationAction { return { type: SHOW_NOTIFICATION, notification: { type: 'error', message } }; } -export function clearNotification() { +interface ClearNotificationAction { + readonly type: typeof CLEAR_NOTIFICATION; +} +export function clearNotification(): ClearNotificationAction { return { type: CLEAR_NOTIFICATION }; } export function getReport(report) { return { type: GET_REPORT_REQUEST, report }; } + +export type StoreAction = + | ChangeSectionAction + | ChangeThemeAction + | ExportAction + | TogglePersistAction + | ToggleSyncAction + | ToggleSliderAction + | ToggleDispatcherAction + | ReconnectAction + | ShowNotificationAction + | ClearNotificationAction; diff --git a/packages/redux-devtools-core/src/app/components/Header.tsx b/packages/redux-devtools-core/src/app/components/Header.tsx index ff80d2b8..c9a42bd2 100644 --- a/packages/redux-devtools-core/src/app/components/Header.tsx +++ b/packages/redux-devtools-core/src/app/components/Header.tsx @@ -1,8 +1,6 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import { Tabs, Toolbar, Button, Divider } from 'devui'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { GoBook } from 'react-icons/go'; import { IoMdText } from 'react-icons/io'; import { TiSocialTwitter } from 'react-icons/ti'; @@ -11,13 +9,14 @@ import { changeSection } from '../actions'; const tabs = [{ name: 'Actions' }, { name: 'Reports' }, { name: 'Settings' }]; -class Header extends Component { - static propTypes = { - section: PropTypes.string.isRequired, - changeSection: PropTypes.func.isRequired, - }; +type DispatchProps = ResolveThunks; +interface OwnProps { + readonly section: string; +} +type Props = DispatchProps & OwnProps; - openLink = (url) => () => { +class Header extends Component { + openLink = (url: string) => () => { window.open(url); }; @@ -69,10 +68,8 @@ class Header extends Component { } } -function mapDispatchToProps(dispatch) { - return { - changeSection: bindActionCreators(changeSection, dispatch), - }; -} +const actionCreators = { + changeSection, +}; -export default connect(null, mapDispatchToProps)(Header); +export default connect(null, actionCreators)(Header); diff --git a/packages/redux-devtools-core/src/app/components/InstanceSelector.tsx b/packages/redux-devtools-core/src/app/components/InstanceSelector.tsx index 3cd30bac..d9bb6991 100644 --- a/packages/redux-devtools-core/src/app/components/InstanceSelector.tsx +++ b/packages/redux-devtools-core/src/app/components/InstanceSelector.tsx @@ -1,17 +1,23 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Select } from 'devui'; import { selectInstance } from '../actions'; +import { StoreState } from '../reducers'; -class InstanceSelector extends Component { +type StateProps = ReturnType; +type DispatchProps = ResolveThunks; +type Props = StateProps & DispatchProps; + +class InstanceSelector extends Component { static propTypes = { selected: PropTypes.string, instances: PropTypes.object.isRequired, onSelect: PropTypes.func.isRequired, }; + select?: { readonly value: string; readonly label: string }[]; + render() { this.select = [{ value: '', label: 'Autoselect instances' }]; const instances = this.props.instances; @@ -19,7 +25,7 @@ class InstanceSelector extends Component { Object.keys(instances).forEach((key) => { name = instances[key].name; if (name !== undefined) - this.select.push({ value: key, label: instances[key].name }); + this.select!.push({ value: key, label: instances[key].name }); }); return ( @@ -32,17 +38,13 @@ class InstanceSelector extends Component { } } -function mapStateToProps(state) { - return { - selected: state.instances.selected, - instances: state.instances.options, - }; -} +const mapStateToProps = (state: StoreState) => ({ + selected: state.instances.selected, + instances: state.instances.options, +}); -function mapDispatchToProps(dispatch) { - return { - onSelect: bindActionCreators(selectInstance, dispatch), - }; -} +const actionCreators = { + onSelect: selectInstance, +}; -export default connect(mapStateToProps, mapDispatchToProps)(InstanceSelector); +export default connect(mapStateToProps, actionCreators)(InstanceSelector); diff --git a/packages/redux-devtools-core/src/app/components/MonitorSelector.tsx b/packages/redux-devtools-core/src/app/components/MonitorSelector.tsx index f0167385..df826bfa 100644 --- a/packages/redux-devtools-core/src/app/components/MonitorSelector.tsx +++ b/packages/redux-devtools-core/src/app/components/MonitorSelector.tsx @@ -1,18 +1,22 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Tabs } from 'devui'; import { monitors } from '../utils/getMonitor'; import { selectMonitor } from '../actions'; +import { StoreState } from '../reducers'; -class MonitorSelector extends Component { +type StateProps = ReturnType; +type DispatchProps = ResolveThunks; +type Props = StateProps & DispatchProps; + +class MonitorSelector extends Component { static propTypes = { selected: PropTypes.string, selectMonitor: PropTypes.func.isRequired, }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: Props) { return nextProps.selected !== this.props.selected; } @@ -30,16 +34,12 @@ class MonitorSelector extends Component { } } -function mapStateToProps(state) { - return { - selected: state.monitor.selected, - }; -} +const mapStateToProps = (state: StoreState) => ({ + selected: state.monitor.selected, +}); -function mapDispatchToProps(dispatch) { - return { - selectMonitor: bindActionCreators(selectMonitor, dispatch), - }; -} +const actionCreators = { + selectMonitor, +}; -export default connect(mapStateToProps, mapDispatchToProps)(MonitorSelector); +export default connect(mapStateToProps, actionCreators)(MonitorSelector); diff --git a/packages/redux-devtools-core/src/app/components/Settings/Connection.tsx b/packages/redux-devtools-core/src/app/components/Settings/Connection.tsx index cb46281e..f6ce3f6b 100644 --- a/packages/redux-devtools-core/src/app/components/Settings/Connection.tsx +++ b/packages/redux-devtools-core/src/app/components/Settings/Connection.tsx @@ -1,9 +1,9 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Container, Form } from 'devui'; import { saveSocketSettings } from '../../actions'; +import { StoreState } from '../../reducers'; const defaultSchema = { type: 'object', @@ -37,19 +37,17 @@ const uiSchema = { }, }; -class Connection extends Component { - static propTypes = { - saveSettings: PropTypes.func.isRequired, - options: PropTypes.object.isRequired, - type: PropTypes.string, - }; +type StateProps = ReturnType; +type DispatchProps = ResolveThunks; +type Props = StateProps & DispatchProps; +class Connection extends Component { constructor(props) { super(props); this.state = this.setFormData(props.type); } - shouldComponentUpdate(nextProps, nextState) { + shouldComponentUpdate(nextProps: Props, nextState) { return this.state !== nextState; } @@ -119,14 +117,10 @@ class Connection extends Component { } } -function mapStateToProps(state) { - return state.connection; -} +const mapStateToProps = (state: StoreState) => state.connection; -function mapDispatchToProps(dispatch) { - return { - saveSettings: bindActionCreators(saveSocketSettings, dispatch), - }; -} +const actionCreators = { + saveSettings: saveSocketSettings, +}; -export default connect(mapStateToProps, mapDispatchToProps)(Connection); +export default connect(mapStateToProps, actionCreators)(Connection); diff --git a/packages/redux-devtools-core/src/app/components/Settings/Themes.tsx b/packages/redux-devtools-core/src/app/components/Settings/Themes.tsx index e528dd55..cd19906a 100644 --- a/packages/redux-devtools-core/src/app/components/Settings/Themes.tsx +++ b/packages/redux-devtools-core/src/app/components/Settings/Themes.tsx @@ -1,17 +1,15 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Container, Form } from 'devui'; import { listSchemes, listThemes } from 'devui/lib/utils/theme'; import { changeTheme } from '../../actions'; +import { StoreState } from '../../reducers'; -class Themes extends Component { - static propTypes = { - changeTheme: PropTypes.func.isRequired, - theme: PropTypes.object.isRequired, - }; +type StateProps = ReturnType; +type DispatchProps = ResolveThunks; +type Props = StateProps & DispatchProps; +class Themes extends Component { render() { const theme = this.props.theme; const formData = { @@ -49,16 +47,12 @@ class Themes extends Component { } } -function mapStateToProps(state) { - return { - theme: state.theme, - }; -} +const mapStateToProps = (state: StoreState) => ({ + theme: state.theme, +}); -function mapDispatchToProps(dispatch) { - return { - changeTheme: bindActionCreators(changeTheme, dispatch), - }; -} +const actionCreators = { + changeTheme, +}; -export default connect(mapStateToProps, mapDispatchToProps)(Themes); +export default connect(mapStateToProps, actionCreators)(Themes); diff --git a/packages/redux-devtools-core/src/app/components/buttons/DispatcherButton.tsx b/packages/redux-devtools-core/src/app/components/buttons/DispatcherButton.tsx index 77f054ae..ed298ccf 100644 --- a/packages/redux-devtools-core/src/app/components/buttons/DispatcherButton.tsx +++ b/packages/redux-devtools-core/src/app/components/buttons/DispatcherButton.tsx @@ -1,18 +1,20 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Button } from 'devui'; import { FaTerminal } from 'react-icons/fa'; import { toggleDispatcher } from '../../actions'; -class DispatcherButton extends Component { +type DispatchProps = ResolveThunks; +type Props = DispatchProps; + +class DispatcherButton extends Component { static propTypes = { dispatcherIsOpen: PropTypes.bool, toggleDispatcher: PropTypes.func.isRequired, }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: Props) { return nextProps.dispatcherIsOpen !== this.props.dispatcherIsOpen; } @@ -32,10 +34,8 @@ class DispatcherButton extends Component { } } -function mapDispatchToProps(dispatch) { - return { - toggleDispatcher: bindActionCreators(toggleDispatcher, dispatch), - }; -} +const actionCreators = { + toggleDispatcher, +}; -export default connect(null, mapDispatchToProps)(DispatcherButton); +export default connect(null, actionCreators)(DispatcherButton); diff --git a/packages/redux-devtools-core/src/app/components/buttons/ExportButton.tsx b/packages/redux-devtools-core/src/app/components/buttons/ExportButton.tsx index 92659c95..959f3c4c 100644 --- a/packages/redux-devtools-core/src/app/components/buttons/ExportButton.tsx +++ b/packages/redux-devtools-core/src/app/components/buttons/ExportButton.tsx @@ -1,12 +1,14 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Button } from 'devui'; import { TiDownload } from 'react-icons/ti'; import { exportState } from '../../actions'; -class ExportButton extends Component { +type DispatchProps = ResolveThunks; +type Props = DispatchProps; + +class ExportButton extends Component { static propTypes = { exportState: PropTypes.func.isRequired, }; @@ -24,10 +26,8 @@ class ExportButton extends Component { } } -function mapDispatchToProps(dispatch) { - return { - exportState: bindActionCreators(exportState, dispatch), - }; -} +const actionCreators = { + exportState, +}; -export default connect(null, mapDispatchToProps)(ExportButton); +export default connect(null, actionCreators)(ExportButton); diff --git a/packages/redux-devtools-core/src/app/components/buttons/PersistButton.tsx b/packages/redux-devtools-core/src/app/components/buttons/PersistButton.tsx index da1c0590..e928ffac 100644 --- a/packages/redux-devtools-core/src/app/components/buttons/PersistButton.tsx +++ b/packages/redux-devtools-core/src/app/components/buttons/PersistButton.tsx @@ -1,19 +1,23 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Button } from 'devui'; import { FaThumbtack } from 'react-icons/fa'; import { togglePersist } from '../../actions'; +import { StoreState } from '../../reducers'; -class LockButton extends Component { +type StateProps = ReturnType; +type DispatchProps = ResolveThunks; +type Props = StateProps & DispatchProps; + +class LockButton extends Component { static propTypes = { persisted: PropTypes.bool, disabled: PropTypes.bool, onClick: PropTypes.func.isRequired, }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: Props) { return nextProps.persisted !== this.props.persisted; } @@ -37,16 +41,12 @@ class LockButton extends Component { } } -function mapStateToProps(state) { - return { - persisted: state.instances.persisted, - }; -} +const mapStateToProps = (state: StoreState) => ({ + persisted: state.instances.persisted, +}); -function mapDispatchToProps(dispatch) { - return { - onClick: bindActionCreators(togglePersist, dispatch), - }; -} +const actionCreators = { + onClick: togglePersist, +}; -export default connect(mapStateToProps, mapDispatchToProps)(LockButton); +export default connect(mapStateToProps, actionCreators)(LockButton); diff --git a/packages/redux-devtools-core/src/app/components/buttons/SliderButton.tsx b/packages/redux-devtools-core/src/app/components/buttons/SliderButton.tsx index 21b842a6..1988edf5 100644 --- a/packages/redux-devtools-core/src/app/components/buttons/SliderButton.tsx +++ b/packages/redux-devtools-core/src/app/components/buttons/SliderButton.tsx @@ -1,18 +1,20 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Button } from 'devui'; import { MdAvTimer } from 'react-icons/md'; import { toggleSlider } from '../../actions'; -class SliderButton extends Component { +type DispatchProps = ResolveThunks; +type Props = DispatchProps; + +class SliderButton extends Component { static propTypes = { isOpen: PropTypes.bool, toggleSlider: PropTypes.func.isRequired, }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: Props) { return nextProps.isOpen !== this.props.isOpen; } @@ -30,10 +32,8 @@ class SliderButton extends Component { } } -function mapDispatchToProps(dispatch) { - return { - toggleSlider: bindActionCreators(toggleSlider, dispatch), - }; -} +const actionCreators = { + toggleSlider, +}; -export default connect(null, mapDispatchToProps)(SliderButton); +export default connect(null, actionCreators)(SliderButton); diff --git a/packages/redux-devtools-core/src/app/components/buttons/SyncButton.tsx b/packages/redux-devtools-core/src/app/components/buttons/SyncButton.tsx index ba37a1d1..406c9c2b 100644 --- a/packages/redux-devtools-core/src/app/components/buttons/SyncButton.tsx +++ b/packages/redux-devtools-core/src/app/components/buttons/SyncButton.tsx @@ -1,18 +1,22 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Button } from 'devui'; import { TiArrowSync } from 'react-icons/ti'; import { toggleSync } from '../../actions'; +import { StoreState } from '../../reducers'; -class SyncButton extends Component { +type StateProps = ReturnType; +type DispatchProps = ResolveThunks; +type Props = StateProps & DispatchProps; + +class SyncButton extends Component { static propTypes = { sync: PropTypes.bool, onClick: PropTypes.func.isRequired, }; - shouldComponentUpdate(nextProps) { + shouldComponentUpdate(nextProps: Props) { return nextProps.sync !== this.props.sync; } @@ -30,16 +34,12 @@ class SyncButton extends Component { } } -function mapStateToProps(state) { - return { - sync: state.instances.sync, - }; -} +const mapStateToProps = (state: StoreState) => ({ + sync: state.instances.sync, +}); -function mapDispatchToProps(dispatch) { - return { - onClick: bindActionCreators(toggleSync, dispatch), - }; -} +const actionCreators = { + onClick: toggleSync, +}; -export default connect(mapStateToProps, mapDispatchToProps)(SyncButton); +export default connect(mapStateToProps, actionCreators)(SyncButton); diff --git a/packages/redux-devtools-core/src/app/containers/Actions.tsx b/packages/redux-devtools-core/src/app/containers/Actions.tsx index 85b6a0ca..3379cbec 100644 --- a/packages/redux-devtools-core/src/app/containers/Actions.tsx +++ b/packages/redux-devtools-core/src/app/containers/Actions.tsx @@ -1,6 +1,5 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { Container } from 'devui'; import SliderMonitor from './monitors/Slider'; @@ -10,6 +9,7 @@ import DevTools from '../containers/DevTools'; import Dispatcher from './monitors/Dispatcher'; import TopButtons from '../components/TopButtons'; import BottomButtons from '../components/BottomButtons'; +import { StoreState } from '../reducers'; class Actions extends Component { render() { @@ -61,7 +61,7 @@ Actions.propTypes = { sliderIsOpen: PropTypes.bool, }; -function mapStateToProps(state) { +const mapStateToProps = (state: StoreState) => { const instances = state.instances; const id = getActiveInstance(instances); return { @@ -73,13 +73,11 @@ function mapStateToProps(state) { sliderIsOpen: state.monitor.sliderIsOpen, reports: state.reports.data, }; -} +}; -function mapDispatchToProps(dispatch) { - return { - liftedDispatch: bindActionCreators(liftedDispatchAction, dispatch), - getReport: bindActionCreators(getReport, dispatch), - }; -} +const actionCreators = { + liftedDispatch: liftedDispatchAction, + getReport, +}; -export default connect(mapStateToProps, mapDispatchToProps)(Actions); +export default connect(mapStateToProps, actionCreators)(Actions); diff --git a/packages/redux-devtools-core/src/app/containers/App.tsx b/packages/redux-devtools-core/src/app/containers/App.tsx index c456800a..39e148d2 100644 --- a/packages/redux-devtools-core/src/app/containers/App.tsx +++ b/packages/redux-devtools-core/src/app/containers/App.tsx @@ -1,14 +1,18 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; +import { connect, ResolveThunks } from 'react-redux'; import { Container, Notification } from 'devui'; import { clearNotification } from '../actions'; import Header from '../components/Header'; import Actions from '../containers/Actions'; import Settings from '../components/Settings'; +import { StoreState } from '../reducers'; -class App extends Component { +type StateProps = ReturnType; +type DispatchProps = ResolveThunks; +type Props = StateProps & DispatchProps; + +class App extends Component { render() { const { section, theme, notification } = this.props; let body; @@ -47,18 +51,14 @@ App.propTypes = { clearNotification: PropTypes.func, }; -function mapStateToProps(state) { - return { - section: state.section, - theme: state.theme, - notification: state.notification, - }; -} +const mapStateToProps = (state: StoreState) => ({ + section: state.section, + theme: state.theme, + notification: state.notification, +}); -function mapDispatchToProps(dispatch) { - return { - clearNotification: bindActionCreators(clearNotification, dispatch), - }; -} +const actionCreators = { + clearNotification, +}; -export default connect(mapStateToProps, mapDispatchToProps)(App); +export default connect(mapStateToProps, actionCreators)(App); diff --git a/packages/redux-devtools-core/src/app/reducers/connection.ts b/packages/redux-devtools-core/src/app/reducers/connection.ts index a9e64411..531dc08b 100644 --- a/packages/redux-devtools-core/src/app/reducers/connection.ts +++ b/packages/redux-devtools-core/src/app/reducers/connection.ts @@ -1,11 +1,22 @@ import { RECONNECT } from '../constants/socketActionTypes'; +import { StoreAction } from '../actions'; + +interface ConnectionOptions { + readonly hostname: string; + readonly port: number; + readonly secure: boolean; +} +export interface ConnectionState { + readonly options: ConnectionOptions; + readonly type: 'disabled' | 'remotedev' | 'custom'; +} export default function connection( - state = { + state: ConnectionState = { options: { hostname: 'localhost', port: 8000, secure: false }, type: 'remotedev', }, - action + action: StoreAction ) { if (action.type === RECONNECT) { const { type, ...options } = action.options; diff --git a/packages/redux-devtools-core/src/app/reducers/index.ts b/packages/redux-devtools-core/src/app/reducers/index.ts index ae099180..272de44b 100644 --- a/packages/redux-devtools-core/src/app/reducers/index.ts +++ b/packages/redux-devtools-core/src/app/reducers/index.ts @@ -1,14 +1,22 @@ import { combineReducers } from 'redux'; -import section from './section'; -import connection from './connection'; +import section, { SectionState } from './section'; +import connection, { ConnectionState } from './connection'; import socket from './socket'; import monitor from './monitor'; -import notification from './notification'; +import notification, { NotificationState } from './notification'; import instances from './instances'; import reports from './reports'; -import theme from './theme'; +import theme, { ThemeState } from './theme'; +import { StoreAction } from '../actions'; -const rootReducer = combineReducers({ +export interface StoreState { + readonly section: SectionState; + readonly theme: ThemeState; + readonly connection: ConnectionState; + readonly notification: NotificationState; +} + +const rootReducer = combineReducers({ section, theme, connection, diff --git a/packages/redux-devtools-core/src/app/reducers/instances.ts b/packages/redux-devtools-core/src/app/reducers/instances.ts index 519e750a..617a17ce 100644 --- a/packages/redux-devtools-core/src/app/reducers/instances.ts +++ b/packages/redux-devtools-core/src/app/reducers/instances.ts @@ -11,6 +11,8 @@ import { DISCONNECTED } from '../constants/socketActionTypes'; import parseJSON from '../utils/parseJSON'; import { recompute } from '../utils/updateState'; +interface InstancesState {} + export const initialState = { selected: null, current: 'default', diff --git a/packages/redux-devtools-core/src/app/reducers/monitor.ts b/packages/redux-devtools-core/src/app/reducers/monitor.ts index f07e2197..c5b31357 100644 --- a/packages/redux-devtools-core/src/app/reducers/monitor.ts +++ b/packages/redux-devtools-core/src/app/reducers/monitor.ts @@ -5,6 +5,7 @@ import { TOGGLE_SLIDER, TOGGLE_DISPATCHER, } from '../constants/actionTypes'; +import { StoreAction } from '../actions'; const initialState = { selected: 'InspectorMonitor', @@ -26,7 +27,7 @@ export function dispatchMonitorAction(state, action) { }; } -export default function monitor(state = initialState, action) { +export default function monitor(state = initialState, action: StoreAction) { switch (action.type) { case MONITOR_ACTION: return dispatchMonitorAction(state, action); diff --git a/packages/redux-devtools-core/src/app/reducers/notification.ts b/packages/redux-devtools-core/src/app/reducers/notification.ts index cf2e59f1..c42e1ee9 100644 --- a/packages/redux-devtools-core/src/app/reducers/notification.ts +++ b/packages/redux-devtools-core/src/app/reducers/notification.ts @@ -4,8 +4,18 @@ import { LIFTED_ACTION, ERROR, } from '../constants/actionTypes'; +import { StoreAction } from '../actions'; -export default function notification(state = null, action) { +interface Notification { + readonly type: 'error'; + readonly message: string; +} +export type NotificationState = Notification | null; + +export default function notification( + state: NotificationState = null, + action: StoreAction +): NotificationState { switch (action.type) { case SHOW_NOTIFICATION: return action.notification; diff --git a/packages/redux-devtools-core/src/app/reducers/reports.ts b/packages/redux-devtools-core/src/app/reducers/reports.ts index 5f825572..8f4f2bd4 100644 --- a/packages/redux-devtools-core/src/app/reducers/reports.ts +++ b/packages/redux-devtools-core/src/app/reducers/reports.ts @@ -1,12 +1,13 @@ import { UPDATE_REPORTS /* , GET_REPORT_SUCCESS */, } from '../constants/actionTypes'; +import { StoreAction } from '../actions'; const initialState = { data: [], }; -export default function reports(state = initialState, action) { +export default function reports(state = initialState, action: StoreAction) { /* if (action.type === GET_REPORT_SUCCESS) { const id = action.data.id; return { diff --git a/packages/redux-devtools-core/src/app/reducers/section.ts b/packages/redux-devtools-core/src/app/reducers/section.ts index 252bdfbb..3497384f 100644 --- a/packages/redux-devtools-core/src/app/reducers/section.ts +++ b/packages/redux-devtools-core/src/app/reducers/section.ts @@ -1,6 +1,9 @@ import { CHANGE_SECTION } from '../constants/actionTypes'; +import { StoreAction } from '../actions'; -export default function section(state = 'Actions', action) { +export type SectionState = string; + +export default function section(state = 'Actions', action: StoreAction) { if (action.type === CHANGE_SECTION) { return action.section; } diff --git a/packages/redux-devtools-core/src/app/reducers/socket.ts b/packages/redux-devtools-core/src/app/reducers/socket.ts index 9d1e9192..4148875d 100644 --- a/packages/redux-devtools-core/src/app/reducers/socket.ts +++ b/packages/redux-devtools-core/src/app/reducers/socket.ts @@ -1,4 +1,5 @@ import * as actions from '../constants/socketActionTypes'; +import { StoreAction } from '../actions'; const initialState = { id: null, @@ -9,7 +10,7 @@ const initialState = { error: undefined, }; -export default function socket(state = initialState, action) { +export default function socket(state = initialState, action: StoreAction) { switch (action.type) { case actions.CONNECT_REQUEST: { return { diff --git a/packages/redux-devtools-core/src/app/reducers/theme.ts b/packages/redux-devtools-core/src/app/reducers/theme.ts index 1fb50905..75353a84 100644 --- a/packages/redux-devtools-core/src/app/reducers/theme.ts +++ b/packages/redux-devtools-core/src/app/reducers/theme.ts @@ -1,8 +1,15 @@ import { CHANGE_THEME } from '../constants/actionTypes'; +import { StoreAction } from '../actions'; + +export interface ThemeState { + readonly theme: 'default' | 'material'; + readonly scheme: string; + readonly light: boolean; +} export default function theme( state = { theme: 'default', scheme: 'default', light: true }, - action + action: StoreAction ) { if (action.type === CHANGE_THEME) { return {