Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Convert entry file to ts #1759

Merged
merged 6 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const env = process.env.NODE_ENV
const extensions = ['.js', '.ts', '.tsx', '.json']

const config = {
input: 'src/index.js',
input: 'src/index.ts',
external: Object.keys(pkg.peerDependencies || {}).concat('react-dom'),
output: {
format: 'umd',
Expand Down
2 changes: 1 addition & 1 deletion src/components/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
import type { FixTypeLater } from '../types'
import { Action, AnyAction, Store } from 'redux'

interface ProviderProps<A extends Action = AnyAction> {
export interface ProviderProps<A extends Action = AnyAction> {
/**
* The single Redux store in your application.
*/
Expand Down
24 changes: 13 additions & 11 deletions src/components/connectAdvanced.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,7 @@ export interface ConnectProps {
store?: Store
}

export type ConnectedComponent<
C extends React.ComponentType<any>,
P
> = React.NamedExoticComponent<JSX.LibraryManagedAttributes<C, P>> & {
WrappedComponent: C
}

interface ConnectAdvancedOptions {
export interface ConnectAdvancedOptions {
getDisplayName?: (name: string) => string
methodName?: string
shouldHandleStateChanges?: boolean
Expand All @@ -189,7 +182,16 @@ interface ConnectAdvancedOptions {
pure?: boolean
}

export default function connectAdvanced(
interface AnyObject {
[x: string]: any
}

export default function connectAdvanced<
S,
TProps,
TOwnProps,
TFactoryOptions extends AnyObject = {}
>(
/*
selectorFactory is a func that is responsible for returning the selector function used to
compute new props from state, props, and dispatch. For example:
Expand All @@ -207,7 +209,7 @@ export default function connectAdvanced(
props. Do not use connectAdvanced directly without memoizing results between calls to your
selector, otherwise the Connect component will re-render on every state or props change.
*/
selectorFactory: SelectorFactory<unknown, unknown, unknown, unknown>,
selectorFactory: SelectorFactory<S, TProps, unknown, unknown>,
// options object:
{
// the func used to compute this HOC's displayName from the wrapped component's displayName.
Expand All @@ -229,7 +231,7 @@ export default function connectAdvanced(

// additional options are passed through to the selectorFactory
...connectOptions
}: ConnectAdvancedOptions = {}
}: ConnectAdvancedOptions & Partial<TFactoryOptions> = {}
) {
const Context = context

Expand Down
29 changes: 28 additions & 1 deletion src/connect/connect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Dispatch } from 'redux'
import connectAdvanced from '../components/connectAdvanced'
import type { ConnectAdvancedOptions } from '../components/connectAdvanced'
import shallowEqual from '../utils/shallowEqual'
import defaultMapDispatchToPropsFactories from './mapDispatchToProps'
import defaultMapStateToPropsFactories from './mapStateToProps'
Expand All @@ -9,6 +10,7 @@ import defaultSelectorFactory, {
MapDispatchToPropsParam,
MergeProps,
} from './selectorFactory'
import type { DefaultRootState } from '../types'

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

export interface ConnectOptions<
State = DefaultRootState,
TStateProps = {},
TOwnProps = {},
TMergedProps = {}
> extends ConnectAdvancedOptions {
pure?: boolean | undefined
areStatesEqual?: ((nextState: State, prevState: State) => boolean) | undefined

areOwnPropsEqual?: (
nextOwnProps: TOwnProps,
prevOwnProps: TOwnProps
) => boolean

areStatePropsEqual?: (
nextStateProps: TStateProps,
prevStateProps: TStateProps
) => boolean
areMergedPropsEqual?: (
nextMergedProps: TMergedProps,
prevMergedProps: TMergedProps
) => boolean
forwardRef?: boolean | undefined
}

// createConnect with default args builds the 'official' connect behavior. Calling it with
// different options opens up some testing and extensibility scenarios
export function createConnect({
Expand All @@ -70,7 +97,7 @@ export function createConnect({
areStatePropsEqual = shallowEqual,
areMergedPropsEqual = shallowEqual,
...extraOptions
} = {}
}: ConnectOptions = {}
) {
const initMapStateToProps = match(
mapStateToProps,
Expand Down
29 changes: 0 additions & 29 deletions src/index.js

This file was deleted.

66 changes: 66 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Provider from './components/Provider'
import type { ProviderProps } from './components/Provider'
import connectAdvanced from './components/connectAdvanced'
import type {
ConnectAdvancedOptions,
ConnectProps,
} from './components/connectAdvanced'
import type {
SelectorFactory,
Selector,
MapStateToProps,
MapStateToPropsFactory,
MapStateToPropsParam,
MapDispatchToPropsFunction,
MapDispatchToProps,
MapDispatchToPropsFactory,
MapDispatchToPropsParam,
MapDispatchToPropsNonObject,
MergeProps,
} from './connect/selectorFactory'
import { ReactReduxContext } from './components/Context'
import type { ReactReduxContextValue } from './components/Context'
import connect from './connect/connect'

import { useDispatch, createDispatchHook } from './hooks/useDispatch'
import { useSelector, createSelectorHook } from './hooks/useSelector'
import { useStore, createStoreHook } from './hooks/useStore'

import { setBatch } from './utils/batch'
import { unstable_batchedUpdates as batch } from './utils/reactBatchedUpdates'
import shallowEqual from './utils/shallowEqual'

setBatch(batch)

export * from './types'
export type {
ProviderProps,
SelectorFactory,
Selector,
MapStateToProps,
MapStateToPropsFactory,
MapStateToPropsParam,
ConnectProps,
ConnectAdvancedOptions,
MapDispatchToPropsFunction,
MapDispatchToProps,
MapDispatchToPropsFactory,
MapDispatchToPropsParam,
MapDispatchToPropsNonObject,
MergeProps,
ReactReduxContextValue,
}
export {
Provider,
connectAdvanced,
ReactReduxContext,
connect,
batch,
useDispatch,
createDispatchHook,
useSelector,
createSelectorHook,
useStore,
createStoreHook,
shallowEqual,
}
19 changes: 19 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,22 @@ export type ResolveArrayThunks<TDispatchProps extends ReadonlyArray<any>> =
: TDispatchProps extends ReadonlyArray<infer A>
? ReadonlyArray<HandleThunkActionCreator<A>>
: never

/**
* This interface allows you to easily create a hook that is properly typed for your
* store's root state.
*
* @example
*
* interface RootState {
* property: string;
* }
*
* const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
*/
export interface TypedUseSelectorHook<TState> {
<TSelected>(
selector: (state: TState) => TSelected,
equalityFn?: (left: TSelected, right: TSelected) => boolean
): TSelected
}
7 changes: 5 additions & 2 deletions test/components/Provider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider, connect, ReactReduxContext } from '../../src/index.js'
import { Provider, connect, ReactReduxContext } from '../../src/index'
import * as rtl from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'

const createExampleTextReducer = () => (state = 'example text') => state
const createExampleTextReducer =
() =>
(state = 'example text') =>
state

describe('React', () => {
describe('Provider', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/components/connect.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import createClass from 'create-react-class'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import { Provider as ProviderMock, connect } from '../../src/index.js'
import { Provider as ProviderMock, connect } from '../../src/index'
import * as rtl from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'

Expand Down
2 changes: 1 addition & 1 deletion test/components/connectAdvanced.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { Component } from 'react'
import * as rtl from '@testing-library/react'
import { Provider as ProviderMock, connectAdvanced } from '../../src/index.js'
import { Provider as ProviderMock, connectAdvanced } from '../../src/index'
import { createStore } from 'redux'
import '@testing-library/jest-dom/extend-expect'

Expand Down
2 changes: 1 addition & 1 deletion test/components/hooks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

Expand Down
2 changes: 1 addition & 1 deletion test/hooks/useDispatch.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
Provider as ProviderMock,
useDispatch,
createDispatchHook,
} from '../../src/index.js'
} from '../../src/index'

const store = createStore((c) => c + 1)
const store2 = createStore((c) => c + 2)
Expand Down
2 changes: 1 addition & 1 deletion test/hooks/useSelector.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
shallowEqual,
connect,
createSelectorHook,
} from '../../src/index.js'
} from '../../src/index'
import { useReduxContext } from '../../src/hooks/useReduxContext'

describe('React', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/integration/dynamic-reducers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { createStore, combineReducers } from 'redux'
import { connect, Provider, ReactReduxContext } from '../../src/index.js'
import { connect, Provider, ReactReduxContext } from '../../src/index'
import * as rtl from '@testing-library/react'

describe('React', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/integration/server-rendering.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import React from 'react'
import { renderToString } from 'react-dom/server'
import { createStore } from 'redux'
import { Provider, connect } from '../../src/index.js'
import { Provider, connect } from '../../src/index'

describe('React', () => {
describe('server rendering', () => {
Expand Down
7 changes: 3 additions & 4 deletions test/react-native/batch-integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
batch,
useSelector,
useDispatch,
} from '../../src/index.js'
} from '../../src/index'
import { useIsomorphicLayoutEffect } from '../../src/utils/useIsomorphicLayoutEffect'
import * as rtl from '@testing-library/react-native'
import '@testing-library/jest-native/extend-expect'
Expand Down Expand Up @@ -468,9 +468,8 @@ describe('React Native', () => {
const rendered = rtl.render(<ReduxBugDemo />)

const assertValuesMatch = (rendered) => {
const [, boolFromSelector] = rendered.getByTestId(
'boolFromSelector'
).children
const [, boolFromSelector] =
rendered.getByTestId('boolFromSelector').children
const [, boolFromStore] = rendered.getByTestId('boolFromStore').children
expect(boolFromSelector).toBe(boolFromStore)
}
Expand Down