Skip to content

Commit 97adc01

Browse files
authoredAug 23, 2020
feature(redux-devtools): convert to TypeScript (#605)
1 parent 07a9919 commit 97adc01

15 files changed

+215
-90
lines changed
 

‎package.json

-6
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
"@babel/preset-typescript": "^7.10.4",
99
"@types/jest": "^26.0.9",
1010
"@types/node": "^14.6.0",
11-
"@types/react": "^16.9.46",
12-
"@types/react-dom": "^16.9.8",
13-
"@types/react-test-renderer": "^16.9.3",
1411
"@types/webpack": "^4.41.21",
1512
"@types/webpack-dev-server": "^3.11.0",
1613
"@typescript-eslint/eslint-plugin": "^3.9.0",
@@ -25,9 +22,6 @@
2522
"jest": "^26.2.2",
2623
"lerna": "^3.22.1",
2724
"prettier": "^2.0.5",
28-
"react": "^16.13.1",
29-
"react-dom": "^16.13.1",
30-
"react-test-renderer": "^16.13.1",
3125
"rimraf": "^3.0.2",
3226
"ts-jest": "^26.2.0",
3327
"ts-node": "^9.0.0",

‎packages/redux-devtools/.babelrc

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
{
2-
"presets": ["@babel/preset-env", "@babel/preset-react"],
2+
"presets": [
3+
"@babel/preset-env",
4+
"@babel/preset-react",
5+
"@babel/preset-typescript"
6+
],
37
"plugins": ["@babel/plugin-proposal-class-properties"]
48
}

‎packages/redux-devtools/.eslintignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
examples
2+
lib
3+
umd

‎packages/redux-devtools/.eslintrc.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module.exports = {
2+
extends: '../../.eslintrc',
3+
overrides: [
4+
{
5+
files: ['*.ts', '*.tsx'],
6+
extends: '../../eslintrc.ts.react.base.json',
7+
parserOptions: {
8+
tsconfigRootDir: __dirname,
9+
project: ['./tsconfig.json'],
10+
},
11+
},
12+
{
13+
files: ['test/*.ts', 'test/*.tsx'],
14+
extends: '../../eslintrc.ts.react.jest.base.json',
15+
parserOptions: {
16+
tsconfigRootDir: __dirname,
17+
project: ['./test/tsconfig.json'],
18+
},
19+
},
20+
],
21+
};

‎packages/redux-devtools/index.d.ts

-18
This file was deleted.
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
};

‎packages/redux-devtools/package.json

+36-34
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,6 @@
22
"name": "redux-devtools",
33
"version": "3.6.1",
44
"description": "Redux DevTools with hot reloading and time travel",
5-
"main": "lib/index.js",
6-
"scripts": {
7-
"clean": "rimraf lib",
8-
"build": "babel src --out-dir lib",
9-
"test": "jest",
10-
"prepare": "npm run build",
11-
"prepublishOnly": "npm run test && npm run clean && npm run build"
12-
},
13-
"files": [
14-
"lib",
15-
"src"
16-
],
17-
"repository": {
18-
"type": "git",
19-
"url": "https://github.com/reduxjs/redux-devtools.git"
20-
},
215
"keywords": [
226
"redux",
237
"devtools",
@@ -26,34 +10,52 @@
2610
"time travel",
2711
"live edit"
2812
],
29-
"author": "Dan Abramov <dan.abramov@me.com> (http://github.com/gaearon)",
30-
"license": "MIT",
13+
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools",
3114
"bugs": {
3215
"url": "https://github.com/reduxjs/redux-devtools/issues"
3316
},
34-
"homepage": "https://github.com/reduxjs/redux-devtools",
17+
"license": "MIT",
18+
"author": "Dan Abramov <dan.abramov@me.com> (http://github.com/gaearon)",
19+
"files": [
20+
"lib",
21+
"src"
22+
],
23+
"main": "lib/index.js",
24+
"types": "lib/index.d.ts",
25+
"repository": {
26+
"type": "git",
27+
"url": "https://github.com/reduxjs/redux-devtools.git"
28+
},
29+
"scripts": {
30+
"build": "npm run build:types && npm run build:js",
31+
"build:types": "tsc --emitDeclarationOnly",
32+
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
33+
"clean": "rimraf lib",
34+
"test": "jest",
35+
"lint": "eslint . --ext .ts,.tsx",
36+
"lint:fix": "eslint . --ext .ts,.tsx --fix",
37+
"type-check": "tsc --noEmit",
38+
"type-check:watch": "npm run type-check -- --watch",
39+
"preversion": "npm run type-check && npm run lint && npm run test",
40+
"prepublishOnly": "npm run clean && npm run build"
41+
},
42+
"dependencies": {
43+
"@types/prop-types": "^15.7.3",
44+
"lodash": "^4.17.19",
45+
"prop-types": "^15.7.2",
46+
"redux-devtools-instrument": "^1.9.7"
47+
},
3548
"devDependencies": {
36-
"@babel/cli": "^7.10.5",
37-
"@babel/core": "^7.11.1",
38-
"@babel/plugin-proposal-class-properties": "^7.10.4",
39-
"@babel/preset-env": "^7.11.0",
40-
"@babel/preset-react": "^7.10.4",
41-
"babel-loader": "^8.1.0",
42-
"jest": "^26.2.2",
49+
"@types/lodash": "^4.14.159",
50+
"@types/react": "^16.3.18",
51+
"@types/react-redux": "^7.1.9",
4352
"react": "^16.13.1",
44-
"react-dom": "^16.13.1",
4553
"react-redux": "^7.2.1",
46-
"redux": "^4.0.5",
47-
"rimraf": "^3.0.2"
54+
"redux": "^4.0.5"
4855
},
4956
"peerDependencies": {
5057
"react": "^0.14.9 || ^15.3.0 || ^16.0.0",
5158
"react-redux": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
5259
"redux": "^3.5.2 || ^4.0.0"
53-
},
54-
"dependencies": {
55-
"lodash": "^4.17.19",
56-
"prop-types": "^15.7.2",
57-
"redux-devtools-instrument": "^1.9.7"
5860
}
5961
}

‎packages/redux-devtools/src/createDevTools.js renamed to ‎packages/redux-devtools/src/createDevTools.tsx

+68-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import React, { Children, Component } from 'react';
22
import PropTypes from 'prop-types';
33
import { connect, Provider, ReactReduxContext } from 'react-redux';
4-
import instrument from 'redux-devtools-instrument';
4+
import instrument, {
5+
EnhancedStore,
6+
LiftedState,
7+
LiftedStore,
8+
Options,
9+
} from 'redux-devtools-instrument';
10+
import { Action } from 'redux';
511

6-
function logError(type) {
7-
/* eslint-disable no-console */
12+
function logError(type: string) {
813
if (type === 'NoStore') {
914
console.error(
1015
'Redux DevTools could not render. You must pass the Redux store ' +
@@ -18,16 +23,51 @@ function logError(type) {
1823
'using createStore()?'
1924
);
2025
}
21-
/* eslint-enable no-console */
2226
}
2327

24-
export default function createDevTools(children) {
28+
interface Props<
29+
S,
30+
A extends Action<unknown>,
31+
MonitorState,
32+
MonitorAction extends Action<unknown>
33+
> {
34+
store?: EnhancedStore<S, A, MonitorState>;
35+
}
36+
37+
type Monitor<
38+
S,
39+
A extends Action<unknown>,
40+
MonitorProps,
41+
MonitorState,
42+
MonitorAction extends Action<unknown>
43+
> = React.ReactElement<
44+
MonitorProps,
45+
React.ComponentType<MonitorProps & LiftedState<S, A, MonitorState>> & {
46+
update(
47+
monitorProps: MonitorProps,
48+
state: MonitorState | undefined,
49+
action: MonitorAction
50+
): MonitorState;
51+
}
52+
>;
53+
54+
export default function createDevTools<
55+
S,
56+
A extends Action<unknown>,
57+
MonitorProps,
58+
MonitorState,
59+
MonitorAction extends Action<unknown>
60+
>(children: Monitor<S, A, MonitorProps, MonitorState, MonitorAction>) {
2561
const monitorElement = Children.only(children);
2662
const monitorProps = monitorElement.props;
2763
const Monitor = monitorElement.type;
28-
const ConnectedMonitor = connect((state) => state)(Monitor);
64+
const ConnectedMonitor = connect(
65+
(state: LiftedState<S, A, MonitorState>) => state
66+
)(Monitor as React.ComponentType<any>);
2967

30-
return class DevTools extends Component {
68+
return class DevTools extends Component<
69+
Props<S, A, MonitorState, MonitorAction>
70+
> {
3171
static contextTypes = {
3272
store: PropTypes.object,
3373
};
@@ -36,13 +76,18 @@ export default function createDevTools(children) {
3676
store: PropTypes.object,
3777
};
3878

39-
static instrument = (options) =>
79+
liftedStore?: LiftedStore<S, A, MonitorState>;
80+
81+
static instrument = (options: Options<S, A, MonitorState, MonitorAction>) =>
4082
instrument(
4183
(state, action) => Monitor.update(monitorProps, state, action),
4284
options
4385
);
4486

45-
constructor(props, context) {
87+
constructor(
88+
props: Props<S, A, MonitorState, MonitorAction>,
89+
context: { store?: EnhancedStore<S, A, MonitorState> }
90+
) {
4691
super(props, context);
4792

4893
if (ReactReduxContext) {
@@ -60,7 +105,7 @@ export default function createDevTools(children) {
60105
if (context.store) {
61106
this.liftedStore = context.store.liftedStore;
62107
} else {
63-
this.liftedStore = props.store.liftedStore;
108+
this.liftedStore = props.store!.liftedStore;
64109
}
65110

66111
if (!this.liftedStore) {
@@ -88,12 +133,23 @@ export default function createDevTools(children) {
88133
logError('NoStore');
89134
return null;
90135
}
91-
if (!props.store.liftedStore) {
136+
if (
137+
!((props.store as unknown) as EnhancedStore<S, A, MonitorState>)
138+
.liftedStore
139+
) {
92140
logError('NoLiftedStore');
93141
return null;
94142
}
95143
return (
96-
<Provider store={props.store.liftedStore}>
144+
<Provider
145+
store={
146+
((props.store as unknown) as EnhancedStore<
147+
S,
148+
A,
149+
MonitorState
150+
>).liftedStore
151+
}
152+
>
97153
<ConnectedMonitor {...monitorProps} />
98154
</Provider>
99155
);

‎packages/redux-devtools/src/persistState.js renamed to ‎packages/redux-devtools/src/persistState.ts

+23-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import mapValues from 'lodash/mapValues';
22
import identity from 'lodash/identity';
3+
import { Action, PreloadedState, Reducer, StoreEnhancer } from 'redux';
4+
import { LiftedState } from 'redux-devtools-instrument';
35

4-
export default function persistState(
5-
sessionId,
6-
deserializeState = identity,
7-
deserializeAction = identity
8-
) {
6+
export default function persistState<
7+
S,
8+
A extends Action<unknown>,
9+
MonitorState
10+
>(
11+
sessionId?: string,
12+
deserializeState: (state: S) => S = identity,
13+
deserializeAction: (action: A) => A = identity
14+
): StoreEnhancer {
915
if (!sessionId) {
1016
return (next) => (...args) => next(...args);
1117
}
1218

13-
function deserialize(state) {
19+
function deserialize(
20+
state: LiftedState<S, A, MonitorState>
21+
): LiftedState<S, A, MonitorState> {
1422
return {
1523
...state,
1624
actionsById: mapValues(state.actionsById, (liftedAction) => ({
@@ -25,7 +33,10 @@ export default function persistState(
2533
};
2634
}
2735

28-
return (next) => (reducer, initialState, enhancer) => {
36+
return (next) => <S, A extends Action<unknown>>(
37+
reducer: Reducer<S, A>,
38+
initialState?: PreloadedState<S>
39+
) => {
2940
const key = `redux-dev-session-${sessionId}`;
3041

3142
let finalInitialState;
@@ -44,11 +55,14 @@ export default function persistState(
4455
}
4556
}
4657

47-
const store = next(reducer, finalInitialState, enhancer);
58+
const store = next(
59+
reducer,
60+
finalInitialState as PreloadedState<S> | undefined
61+
);
4862

4963
return {
5064
...store,
51-
dispatch(action) {
65+
dispatch<T extends A>(action: T) {
5266
store.dispatch(action);
5367

5468
try {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare namespace NodeJS {
2+
interface Global {
3+
localStorage: Storage;
4+
}
5+
}

0 commit comments

Comments
 (0)
Please sign in to comment.