Skip to content

Commit 17ddf9d

Browse files
authored
Convert entry file to ts (#1759)
1 parent 147f178 commit 17ddf9d

16 files changed

+143
-56
lines changed

rollup.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const env = process.env.NODE_ENV
1010
const extensions = ['.js', '.ts', '.tsx', '.json']
1111

1212
const config = {
13-
input: 'src/index.js',
13+
input: 'src/index.ts',
1414
external: Object.keys(pkg.peerDependencies || {}).concat('react-dom'),
1515
output: {
1616
format: 'umd',

src/components/Provider.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
55
import type { FixTypeLater } from '../types'
66
import { Action, AnyAction, Store } from 'redux'
77

8-
interface ProviderProps<A extends Action = AnyAction> {
8+
export interface ProviderProps<A extends Action = AnyAction> {
99
/**
1010
* The single Redux store in your application.
1111
*/

src/components/connectAdvanced.tsx

+13-11
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,7 @@ export interface ConnectProps {
173173
store?: Store
174174
}
175175

176-
export type ConnectedComponent<
177-
C extends React.ComponentType<any>,
178-
P
179-
> = React.NamedExoticComponent<JSX.LibraryManagedAttributes<C, P>> & {
180-
WrappedComponent: C
181-
}
182-
183-
interface ConnectAdvancedOptions {
176+
export interface ConnectAdvancedOptions {
184177
getDisplayName?: (name: string) => string
185178
methodName?: string
186179
shouldHandleStateChanges?: boolean
@@ -189,7 +182,16 @@ interface ConnectAdvancedOptions {
189182
pure?: boolean
190183
}
191184

192-
export default function connectAdvanced(
185+
interface AnyObject {
186+
[x: string]: any
187+
}
188+
189+
export default function connectAdvanced<
190+
S,
191+
TProps,
192+
TOwnProps,
193+
TFactoryOptions extends AnyObject = {}
194+
>(
193195
/*
194196
selectorFactory is a func that is responsible for returning the selector function used to
195197
compute new props from state, props, and dispatch. For example:
@@ -207,7 +209,7 @@ export default function connectAdvanced(
207209
props. Do not use connectAdvanced directly without memoizing results between calls to your
208210
selector, otherwise the Connect component will re-render on every state or props change.
209211
*/
210-
selectorFactory: SelectorFactory<unknown, unknown, unknown, unknown>,
212+
selectorFactory: SelectorFactory<S, TProps, unknown, unknown>,
211213
// options object:
212214
{
213215
// the func used to compute this HOC's displayName from the wrapped component's displayName.
@@ -229,7 +231,7 @@ export default function connectAdvanced(
229231

230232
// additional options are passed through to the selectorFactory
231233
...connectOptions
232-
}: ConnectAdvancedOptions = {}
234+
}: ConnectAdvancedOptions & Partial<TFactoryOptions> = {}
233235
) {
234236
const Context = context
235237

src/connect/connect.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Dispatch } from 'redux'
22
import connectAdvanced from '../components/connectAdvanced'
3+
import type { ConnectAdvancedOptions } from '../components/connectAdvanced'
34
import shallowEqual from '../utils/shallowEqual'
45
import defaultMapDispatchToPropsFactories from './mapDispatchToProps'
56
import defaultMapStateToPropsFactories from './mapStateToProps'
@@ -9,6 +10,7 @@ import defaultSelectorFactory, {
910
MapDispatchToPropsParam,
1011
MergeProps,
1112
} from './selectorFactory'
13+
import type { DefaultRootState } from '../types'
1214

1315
/*
1416
connect is a facade over connectAdvanced. It turns its args into a compatible
@@ -50,6 +52,31 @@ function strictEqual(a: unknown, b: unknown) {
5052
return a === b
5153
}
5254

55+
export interface ConnectOptions<
56+
State = DefaultRootState,
57+
TStateProps = {},
58+
TOwnProps = {},
59+
TMergedProps = {}
60+
> extends ConnectAdvancedOptions {
61+
pure?: boolean | undefined
62+
areStatesEqual?: ((nextState: State, prevState: State) => boolean) | undefined
63+
64+
areOwnPropsEqual?: (
65+
nextOwnProps: TOwnProps,
66+
prevOwnProps: TOwnProps
67+
) => boolean
68+
69+
areStatePropsEqual?: (
70+
nextStateProps: TStateProps,
71+
prevStateProps: TStateProps
72+
) => boolean
73+
areMergedPropsEqual?: (
74+
nextMergedProps: TMergedProps,
75+
prevMergedProps: TMergedProps
76+
) => boolean
77+
forwardRef?: boolean | undefined
78+
}
79+
5380
// createConnect with default args builds the 'official' connect behavior. Calling it with
5481
// different options opens up some testing and extensibility scenarios
5582
export function createConnect({
@@ -70,7 +97,7 @@ export function createConnect({
7097
areStatePropsEqual = shallowEqual,
7198
areMergedPropsEqual = shallowEqual,
7299
...extraOptions
73-
} = {}
100+
}: ConnectOptions = {}
74101
) {
75102
const initMapStateToProps = match(
76103
mapStateToProps,

src/index.js

-29
This file was deleted.

src/index.ts

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import Provider from './components/Provider'
2+
import type { ProviderProps } from './components/Provider'
3+
import connectAdvanced from './components/connectAdvanced'
4+
import type {
5+
ConnectAdvancedOptions,
6+
ConnectProps,
7+
} from './components/connectAdvanced'
8+
import type {
9+
SelectorFactory,
10+
Selector,
11+
MapStateToProps,
12+
MapStateToPropsFactory,
13+
MapStateToPropsParam,
14+
MapDispatchToPropsFunction,
15+
MapDispatchToProps,
16+
MapDispatchToPropsFactory,
17+
MapDispatchToPropsParam,
18+
MapDispatchToPropsNonObject,
19+
MergeProps,
20+
} from './connect/selectorFactory'
21+
import { ReactReduxContext } from './components/Context'
22+
import type { ReactReduxContextValue } from './components/Context'
23+
import connect from './connect/connect'
24+
25+
import { useDispatch, createDispatchHook } from './hooks/useDispatch'
26+
import { useSelector, createSelectorHook } from './hooks/useSelector'
27+
import { useStore, createStoreHook } from './hooks/useStore'
28+
29+
import { setBatch } from './utils/batch'
30+
import { unstable_batchedUpdates as batch } from './utils/reactBatchedUpdates'
31+
import shallowEqual from './utils/shallowEqual'
32+
33+
setBatch(batch)
34+
35+
export * from './types'
36+
export type {
37+
ProviderProps,
38+
SelectorFactory,
39+
Selector,
40+
MapStateToProps,
41+
MapStateToPropsFactory,
42+
MapStateToPropsParam,
43+
ConnectProps,
44+
ConnectAdvancedOptions,
45+
MapDispatchToPropsFunction,
46+
MapDispatchToProps,
47+
MapDispatchToPropsFactory,
48+
MapDispatchToPropsParam,
49+
MapDispatchToPropsNonObject,
50+
MergeProps,
51+
ReactReduxContextValue,
52+
}
53+
export {
54+
Provider,
55+
connectAdvanced,
56+
ReactReduxContext,
57+
connect,
58+
batch,
59+
useDispatch,
60+
createDispatchHook,
61+
useSelector,
62+
createSelectorHook,
63+
useStore,
64+
createStoreHook,
65+
shallowEqual,
66+
}

src/types.ts

+19
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,22 @@ export type ResolveArrayThunks<TDispatchProps extends ReadonlyArray<any>> =
256256
: TDispatchProps extends ReadonlyArray<infer A>
257257
? ReadonlyArray<HandleThunkActionCreator<A>>
258258
: never
259+
260+
/**
261+
* This interface allows you to easily create a hook that is properly typed for your
262+
* store's root state.
263+
*
264+
* @example
265+
*
266+
* interface RootState {
267+
* property: string;
268+
* }
269+
*
270+
* const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
271+
*/
272+
export interface TypedUseSelectorHook<TState> {
273+
<TSelected>(
274+
selector: (state: TState) => TSelected,
275+
equalityFn?: (left: TSelected, right: TSelected) => boolean
276+
): TSelected
277+
}

test/components/Provider.spec.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import React, { Component } from 'react'
44
import ReactDOM from 'react-dom'
55
import { createStore } from 'redux'
6-
import { Provider, connect, ReactReduxContext } from '../../src/index.js'
6+
import { Provider, connect, ReactReduxContext } from '../../src/index'
77
import * as rtl from '@testing-library/react'
88
import '@testing-library/jest-dom/extend-expect'
99

10-
const createExampleTextReducer = () => (state = 'example text') => state
10+
const createExampleTextReducer =
11+
() =>
12+
(state = 'example text') =>
13+
state
1114

1215
describe('React', () => {
1316
describe('Provider', () => {

test/components/connect.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import createClass from 'create-react-class'
55
import PropTypes from 'prop-types'
66
import ReactDOM from 'react-dom'
77
import { createStore, applyMiddleware } from 'redux'
8-
import { Provider as ProviderMock, connect } from '../../src/index.js'
8+
import { Provider as ProviderMock, connect } from '../../src/index'
99
import * as rtl from '@testing-library/react'
1010
import '@testing-library/jest-dom/extend-expect'
1111

test/components/connectAdvanced.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component } from 'react'
22
import * as rtl from '@testing-library/react'
3-
import { Provider as ProviderMock, connectAdvanced } from '../../src/index.js'
3+
import { Provider as ProviderMock, connectAdvanced } from '../../src/index'
44
import { createStore } from 'redux'
55
import '@testing-library/jest-dom/extend-expect'
66

test/components/hooks.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import React from 'react'
44
import { createStore } from 'redux'
5-
import { Provider as ProviderMock, connect } from '../../src/index.js'
5+
import { Provider as ProviderMock, connect } from '../../src/index'
66
import * as rtl from '@testing-library/react'
77
import '@testing-library/jest-dom/extend-expect'
88

test/hooks/useDispatch.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
Provider as ProviderMock,
66
useDispatch,
77
createDispatchHook,
8-
} from '../../src/index.js'
8+
} from '../../src/index'
99

1010
const store = createStore((c) => c + 1)
1111
const store2 = createStore((c) => c + 2)

test/hooks/useSelector.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
shallowEqual,
1111
connect,
1212
createSelectorHook,
13-
} from '../../src/index.js'
13+
} from '../../src/index'
1414
import { useReduxContext } from '../../src/hooks/useReduxContext'
1515

1616
describe('React', () => {

test/integration/dynamic-reducers.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import React from 'react'
44
import ReactDOMServer from 'react-dom/server'
55
import { createStore, combineReducers } from 'redux'
6-
import { connect, Provider, ReactReduxContext } from '../../src/index.js'
6+
import { connect, Provider, ReactReduxContext } from '../../src/index'
77
import * as rtl from '@testing-library/react'
88

99
describe('React', () => {

test/integration/server-rendering.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import React from 'react'
1212
import { renderToString } from 'react-dom/server'
1313
import { createStore } from 'redux'
14-
import { Provider, connect } from '../../src/index.js'
14+
import { Provider, connect } from '../../src/index'
1515

1616
describe('React', () => {
1717
describe('server rendering', () => {

test/react-native/batch-integration.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
batch,
88
useSelector,
99
useDispatch,
10-
} from '../../src/index.js'
10+
} from '../../src/index'
1111
import { useIsomorphicLayoutEffect } from '../../src/utils/useIsomorphicLayoutEffect'
1212
import * as rtl from '@testing-library/react-native'
1313
import '@testing-library/jest-native/extend-expect'
@@ -468,9 +468,8 @@ describe('React Native', () => {
468468
const rendered = rtl.render(<ReduxBugDemo />)
469469

470470
const assertValuesMatch = (rendered) => {
471-
const [, boolFromSelector] = rendered.getByTestId(
472-
'boolFromSelector'
473-
).children
471+
const [, boolFromSelector] =
472+
rendered.getByTestId('boolFromSelector').children
474473
const [, boolFromStore] = rendered.getByTestId('boolFromStore').children
475474
expect(boolFromSelector).toBe(boolFromStore)
476475
}

0 commit comments

Comments
 (0)