Fix linting error in packages/redux

This commit is contained in:
Jerko Steiner 2019-09-15 16:20:52 +07:00
parent 8c732ba91e
commit 003032c3ef
27 changed files with 216 additions and 106 deletions

View File

@ -1,7 +1,11 @@
extends:
- eslint:recommended
- plugin:react/recommended
- plugin:@typescript-eslint/eslint-recommended
- plugin:@typescript-eslint/recommended
settings:
react:
version: 'detect'
rules:
max-len:
- warn

116
package-lock.json generated
View File

@ -3059,6 +3059,16 @@
"integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
"dev": true
},
"array-includes": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
"integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.7.0"
}
},
"array-map": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
@ -6455,6 +6465,54 @@
}
}
},
"eslint-plugin-react": {
"version": "7.14.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz",
"integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==",
"dev": true,
"requires": {
"array-includes": "^3.0.3",
"doctrine": "^2.1.0",
"has": "^1.0.3",
"jsx-ast-utils": "^2.1.0",
"object.entries": "^1.1.0",
"object.fromentries": "^2.0.0",
"object.values": "^1.1.0",
"prop-types": "^15.7.2",
"resolve": "^1.10.1"
},
"dependencies": {
"doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
"dev": true,
"requires": {
"esutils": "^2.0.2"
}
},
"prop-types": {
"version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"dev": true,
"requires": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.8.1"
}
},
"resolve": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
}
}
},
"eslint-scope": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
@ -10112,6 +10170,16 @@
"verror": "1.10.0"
}
},
"jsx-ast-utils": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz",
"integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==",
"dev": true,
"requires": {
"array-includes": "^3.0.3",
"object.assign": "^4.1.0"
}
},
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
@ -11700,6 +11768,42 @@
"isobject": "^3.0.0"
}
},
"object.assign": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"function-bind": "^1.1.1",
"has-symbols": "^1.0.0",
"object-keys": "^1.0.11"
}
},
"object.entries": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz",
"integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.12.0",
"function-bind": "^1.1.1",
"has": "^1.0.3"
}
},
"object.fromentries": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz",
"integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.11.0",
"function-bind": "^1.1.1",
"has": "^1.0.1"
}
},
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
@ -11719,6 +11823,18 @@
"isobject": "^3.0.1"
}
},
"object.values": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz",
"integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.12.0",
"function-bind": "^1.1.1",
"has": "^1.0.3"
}
},
"octokit-pagination-methods": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz",

View File

@ -59,6 +59,7 @@
"common-shakeify": "^0.6.0",
"cookie-parser": "^1.4.4",
"deep-object-diff": "^1.1.0",
"eslint-plugin-react": "^7.14.3",
"esmify": "git+https://github.com/jeremija/esmify.git",
"formik": "^1.5.8",
"history": "^4.9.0",

View File

@ -0,0 +1,4 @@
export interface Action<T, ActionType extends string> {
payload: T
type: ActionType
}

View File

@ -0,0 +1,10 @@
import {PendingAction} from './PendingAction'
import {ResolvedAction} from './ResolvedAction'
import {RejectedAction} from './RejectedAction'
export type TAsyncStatus = 'pending' | 'resolved' | 'rejected'
export type AsyncAction<T, ActionType extends string> =
PendingAction<T, ActionType>
| ResolvedAction<T, ActionType>
| RejectedAction<ActionType>

View File

@ -1,6 +1,6 @@
import {IAction} from './IAction'
import {Action} from './Action'
export type TGetAction<ActionTypes, T extends string> =
ActionTypes extends IAction<infer U, T>
ActionTypes extends Action<infer U, T>
? ActionTypes
: never

View File

@ -0,0 +1,6 @@
import {AsyncAction} from './AsyncAction'
export type GetPendingAction<MyTypes, T extends string> =
MyTypes extends AsyncAction<infer U, T> & {status: 'pending'}
? MyTypes
: never

View File

@ -0,0 +1,6 @@
import {AsyncAction} from './AsyncAction'
export type GetResolvedAction<MyTypes, T extends string> =
MyTypes extends AsyncAction<infer U, T> & {status: 'resolved'}
? MyTypes
: never

View File

@ -1,4 +0,0 @@
export interface IAction<T, ActionType extends string> {
payload: T
type: ActionType
}

View File

@ -1,6 +0,0 @@
import {IAction} from './IAction'
export interface IPendingAction<T, ActionType extends string> extends
IAction<Promise<T>, ActionType> {
status: 'pending'
}

View File

@ -1,6 +0,0 @@
import {IAction} from './IAction'
export interface IRejectedAction<ActionType extends string> extends
IAction<Error, ActionType> {
status: 'rejected'
}

View File

@ -1,7 +0,0 @@
import {IAction} from './IAction'
export interface IResolvedAction<T, ActionType extends string> extends
IAction<T, ActionType> {
payload: T
status: 'resolved'
}

View File

@ -1,9 +1,6 @@
import {IPendingAction} from './IPendingAction'
import {Action} from './Action'
export class PendingAction<T, ActionType extends string> {
readonly status = 'pending'
constructor(
readonly payload: T,
readonly type: ActionType,
) {}
export interface PendingAction<T, ActionType extends string> extends
Action<Promise<T>, ActionType> {
status: 'pending'
}

View File

@ -0,0 +1,6 @@
import {Action} from './Action'
export interface RejectedAction<ActionType extends string> extends
Action<Error, ActionType> {
status: 'rejected'
}

View File

@ -0,0 +1,7 @@
import {Action} from './Action'
export interface ResolvedAction<T, ActionType extends string> extends
Action<T, ActionType> {
payload: T
status: 'resolved'
}

View File

@ -1,10 +0,0 @@
import {IPendingAction} from './IPendingAction'
import {IResolvedAction} from './IResolvedAction'
import {IRejectedAction} from './IRejectedAction'
export type TAsyncStatus = 'pending' | 'resolved' | 'rejected'
export type TAsyncAction<T, ActionType extends string> =
IPendingAction<T, ActionType>
| IResolvedAction<T, ActionType>
| IRejectedAction<ActionType>

View File

@ -1,6 +0,0 @@
import {TAsyncAction} from './TAsyncAction'
export type TGetPendingAction<MyTypes, T extends string> =
MyTypes extends TAsyncAction<infer U, T> & {status: 'pending'}
? MyTypes
: never

View File

@ -1,6 +0,0 @@
import {TAsyncAction} from './TAsyncAction'
export type TGetResolvedAction<MyTypes, T extends string> =
MyTypes extends TAsyncAction<infer U, T> & {status: 'resolved'}
? MyTypes
: never

View File

@ -0,0 +1,8 @@
import {PendingAction} from './IPendingAction'
export function createPendingAction<T, ActionType extends string>(
payload: Promise<T>,
type: ActionType,
): PendingAction<T, ActionType> {
return {payload, type, status: 'pending'}
}

View File

@ -1,9 +1,9 @@
export * from './IAction'
export * from './IPendingAction'
export * from './IRejectedAction'
export * from './IResolvedAction'
export * from './Action'
export * from './createPendingAction'
export * from './RejectedAction'
export * from './ResolvedAction'
export * from './PendingAction'
export * from './TAsyncAction'
export * from './TGetAction'
export * from './TGetPendingAction'
export * from './TGetResolvedAction'
export * from './AsyncAction'
export * from './GetAction'
export * from './GetPendingAction'
export * from './GetResolvedAction'

View File

@ -4,5 +4,5 @@ export function bindActionCreators<T extends object>(
obj: T,
dispatch: Dispatch,
): T {
return bind(obj as any, dispatch)
return bind(obj as any, dispatch) // eslint-disable-line
}

View File

@ -1,9 +1,8 @@
import assert from 'assert'
import {AnyAction, Middleware} from 'redux'
function isPromise(value: any): value is Promise<any> {
function isPromise(value: unknown): value is Promise<unknown> {
return value && typeof value === 'object' &&
typeof (value as any).then === 'function'
typeof (value as Promise<unknown>).then === 'function'
}
/**
@ -21,7 +20,7 @@ function isPromise(value: any): value is Promise<any> {
*/
export class PromiseMiddleware {
handle: Middleware = store => next => (action: AnyAction) => {
const {payload, type} = action
const {payload} = action
if (!isPromise(payload)) {
return next(action)
}

View File

@ -1,14 +1,12 @@
import {WaitMiddleware} from './WaitMiddleware'
import {
IAction, IPendingAction, IResolvedAction, IRejectedAction,
} from '../actions'
import {applyMiddleware, createStore, AnyAction} from 'redux'
import { getError } from '@rondo.dev/test-utils'
import { applyMiddleware, createStore } from 'redux'
import { Action } from '../actions'
import { WaitMiddleware } from './WaitMiddleware'
describe('WaitMiddleware', () => {
const getStore = (wm: WaitMiddleware) => createStore(
(state: string[] = [], action: IAction<any, string>) => {
(state: string[] = [], action: Action<any, string>) => {
return [...state, action.type]
},
[],

View File

@ -1,15 +1,15 @@
import {TAsyncAction} from '../actions/TAsyncAction'
import {AsyncAction} from '../actions/AsyncAction'
import {AnyAction, Middleware} from 'redux'
export class WaitMiddleware {
protected notify?: (action: TAsyncAction<any, string>) => void
protected notify?: (action: AsyncAction<unknown, string>) => void
protected recorders: Recorder[] = []
handle: Middleware = store => next => (action: AnyAction) => {
handle: Middleware = () => next => (action: AnyAction) => {
next(action)
this.recorders.forEach(recorder => recorder.record(action))
if (this.notify && 'status' in action) {
this.notify(action as TAsyncAction<any, string>)
this.notify(action as AsyncAction<unknown, string>)
}
}
@ -66,7 +66,7 @@ export class WaitMiddleware {
this.notify = undefined
}, timeout)
this.notify = (action: TAsyncAction<any, string>) => {
this.notify = (action: AsyncAction<unknown, string>) => {
if (!actionsByName[action.type]) {
return
}
@ -77,11 +77,13 @@ export class WaitMiddleware {
actionsByName[action.type]--
count--
if (count === 0) {
clearTimeout(t)
resolve()
this.notify = undefined
}
return
case 'rejected':
clearTimeout(t)
reject(action.payload)
this.notify = undefined
return

View File

@ -7,19 +7,19 @@ import { pack, TStateSelector } from './pack'
describe('pack', () => {
interface IChangeAction {
payload: {a: number, b: string},
interface ChangeAction {
payload: {a: number, b: string}
type: 'CHANGE'
}
interface IProps {
interface Props {
a: number
b: string
update(a: number, b: string): IChangeAction
update(a: number, b: string): ChangeAction
c: string[]
}
class PureComponent extends React.PureComponent<IProps> {
class PureComponent extends React.PureComponent<Props> {
update = () => {
this.props.update(1, 'one')
}
@ -34,7 +34,7 @@ describe('pack', () => {
}
}
function FunctionalComponent(props: IProps) {
function FunctionalComponent(props: Props) {
const update = useCallback(() => props.update(1, 'one'), [])
return (
@ -44,15 +44,15 @@ describe('pack', () => {
)
}
type LocalState = Omit<IProps, 'c' | 'update'>
interface IState {
type LocalState = Omit<Props, 'c' | 'update'>
interface State {
localState: LocalState
}
function reduce(
state: IState = {localState: {a: 0, b: ''}},
state: State = {localState: {a: 0, b: ''}},
action: any,
): IState {
): State {
switch (action.type) {
case 'CHANGE':
return {
@ -73,7 +73,7 @@ describe('pack', () => {
getLocalState,
(localState: LocalState) => localState,
{
update(a: number, b: string): IChangeAction {
update(a: number, b: string): ChangeAction {
return {
payload: {a, b},
type: 'CHANGE',
@ -91,7 +91,7 @@ describe('pack', () => {
getLocalState,
(localState: LocalState) => localState,
{
update(a: number, b: string): IChangeAction {
update(a: number, b: string): ChangeAction {
return {
payload: {a, b},
type: 'CHANGE',
@ -102,10 +102,10 @@ describe('pack', () => {
)
}
const PackedPureComponent = configurePureComponent<IState>(
const PackedPureComponent = configurePureComponent<State>(
state => state.localState)
const PackedFunctionalComponent = configureFunctionalComponent<IState>(
const PackedFunctionalComponent = configureFunctionalComponent<State>(
state => state.localState)
it('creates a connected component', () => {

View File

@ -1,6 +1,4 @@
import { ComponentType, PureComponent } from 'react'
import { connect, Omit, MapDispatchToPropsParam, Matching, GetProps, ResolveThunks } from 'react-redux'
import { Dispatch } from 'redux'
import { connect, GetProps, MapDispatchToPropsParam, Matching, ResolveThunks } from 'react-redux'
/*
* Select and return a part of the state

View File

@ -1,14 +1,7 @@
import {ReduxLogger, PromiseMiddleware, WaitMiddleware} from '../middleware'
import {
applyMiddleware,
createStore as create,
Middleware,
Action,
DeepPartial,
Reducer,
} from 'redux'
import { Action, applyMiddleware, createStore as create, DeepPartial, Middleware, Reducer } from 'redux'
import { PromiseMiddleware, ReduxLogger } from '../middleware'
export interface ICreateStoreParams<State, A extends Action> {
export interface CreateStoreParams<State, A extends Action> {
reducer: Reducer<State, A>
state?: Partial<State>
middleware?: Middleware[]
@ -19,7 +12,7 @@ export interface ICreateStoreParams<State, A extends Action> {
* Create a Redux store.
*/
export function createStore<State, A extends Action>(
params: ICreateStoreParams<State, A>,
params: CreateStoreParams<State, A>,
) {
const middleware = params.middleware || [
new ReduxLogger(