ronantakizawa/codereview-bench huggingface dataset:
Repository: pmndrs/zustand
File: rollup.config.js (JavaScript)

Code before:
      format: 'umd',
      exports: 'named',
      name: 'zustand',
      esModule: true,
    },
    external,
    plugins: [
      resolve({ extensions }),
      babelPlugin(getBabelOptions({ ie: 11 })),
    ],
  }
}

function createSystemConfig(input, output) {
  return {
    input,
    output: {
      file: output,
      format: 'system',
      exports: 'named',
      esModule: true,
    },
    external,
    plugins: [
      resolve({ extensions }),
      babelPlugin(getBabelOptions({ ie: 11 })),
    ],
  }
}

export default function (args) {
  let c = Object.keys(args).find((key) => key.startsWith('config-'))
  if (c) {
    c = c.slice('config-'.length).replace(/_/g, '/')
    return [
      createCommonJSConfig(`src/${c}.ts`, `dist/${c}.js`),
      createESMConfig(`src/${c}.ts`, `dist/esm/${c}`),
      createUMDConfig(`src/${c}.ts`, `dist/umd/${c}.js`),
      createSystemConfig(`src/${c}.ts`, `dist/system/${c}.js`),
    ]
  }
  return [
    createDeclarationConfig('src/index.ts', 'dist'),
    createCommonJSConfig('src/index.ts', 'dist/index.js'),
    createESMConfig('src/index.ts', 'dist/esm/index'),
    createUMDConfig('src/index.ts', 'dist/umd/index.js'),
    createSystemConfig('src/index.ts', 'dist/system/index.js'),
  ]
}


Review comment (performance):
Do systemjs users need old browser support? (they can use umd in such cases?)
otherwise,
```suggestion
      getEsbuild('node12'),
```
would build more efficient output?

Code after:
      format: 'umd',
      exports: 'named',
      name: 'zustand',
    },
    external,
    plugins: [
      resolve({ extensions }),
      babelPlugin(getBabelOptions({ ie: 11 })),
    ],
  }
}

function createSystemConfig(input, output) {
  return {
    input,
    output: {
      file: output,
      format: 'system',
      exports: 'named',
    },
    external,
    plugins: [resolve({ extensions }), getEsbuild('node12')],
  }
}

export default function (args) {
  let c = Object.keys(args).find((key) => key.startsWith('config-'))
  if (c) {
    c = c.slice('config-'.length).replace(/_/g, '/')
    return [
      createCommonJSConfig(`src/${c}.ts`, `dist/${c}.js`),
      createESMConfig(`src/${c}.ts`, `dist/esm/${c}`),
      createUMDConfig(`src/${c}.ts`, `dist/umd/${c}.js`),
      createSystemConfig(`src/${c}.ts`, `dist/system/${c}.js`),
    ]
  }
  return [
    createDeclarationConfig('src/index.ts', 'dist'),
    createCommonJSConfig('src/index.ts', 'dist/index.js'),
    createESMConfig('src/index.ts', 'dist/esm/index'),
    createUMDConfig('src/index.ts', 'dist/umd/index.js'),
    createSystemConfig('src/index.ts', 'dist/system/index.js'),
  ]
}
Repository: pmndrs/zustand
File: examples/src/components/Details.js (JavaScript)

Code before:
import React from 'react'

export default function () {
  return (
    <>
      <a href="https://github.com/drcmda/zustand" className="top-right" children="Github" />
      <div className="bottom">
        <a href="https://codesandbox.io/s/xgjtc" className="bottom-right" children="<Source />" />
        <a
          href="https://www.instagram.com/tina.henschel/"
          className="bottom-left"
          children="Illustrations @ Tina Henschel"
        />
      </div>
      <span className="header-left">Zustand</span>
    </>
  )
}


Review comment (suggestion):
```suggestion
      <a href="https://github.com/pmndrs/zustand" className="top-right" children="Github" />
```

Code after:
import React from 'react'

export default function () {
  return (
    <>
      <a href="https://github.com/pmndrs/zustand" className="top-right" children="Github" />
      <div className="bottom">
        <a href="https://github.com/pmndrs/zustand/tree/main/examples" className="bottom-right" children="<Source />" />
        <a
          href="https://www.instagram.com/tina.henschel/"
          className="bottom-left"
          children="Illustrations @ Tina Henschel"
        />
      </div>
      <span className="header-left">Zustand</span>
    </>
  )
}
Repository: pmndrs/zustand
File: examples/src/components/Details.js (JavaScript)

Code before:
import React from 'react'

export default function () {
  return (
    <>
      <a href="https://github.com/drcmda/zustand" className="top-right" children="Github" />
      <div className="bottom">
        <a href="https://codesandbox.io/s/xgjtc" className="bottom-right" children="<Source />" />
        <a
          href="https://www.instagram.com/tina.henschel/"
          className="bottom-left"
          children="Illustrations @ Tina Henschel"
        />
      </div>
      <span className="header-left">Zustand</span>
    </>
  )
}


Review comment (suggestion):
```suggestion
        <a href="https://github.com/pmndrs/zustand/tree/main/examples" className="bottom-right" children="<Source />" />
```

Code after:
import React from 'react'

export default function () {
  return (
    <>
      <a href="https://github.com/pmndrs/zustand" className="top-right" children="Github" />
      <div className="bottom">
        <a href="https://github.com/pmndrs/zustand/tree/main/examples" className="bottom-right" children="<Source />" />
        <a
          href="https://www.instagram.com/tina.henschel/"
          className="bottom-left"
          children="Illustrations @ Tina Henschel"
        />
      </div>
      <span className="header-left">Zustand</span>
    </>
  )
}
Repository: pmndrs/zustand
File: src/middleware/redux.ts (TypeScript)

Code before:
  init: (state: any) => void
  error: (payload: any) => void
}

/**
 * @deprecated Use `Mutate<StoreApi<T & { dispatch: (a: A) => A }>, [["zustand/redux", A]]>`.
 * See tests/middlewaresTypes.test.tsx for usage with multiple middlewares.
 */
export type StoreApiWithRedux<
  T extends State,
  A extends { type: unknown }
> = StoreApi<T & { dispatch: (a: A) => A }> & {
  dispatch: (a: A) => A
  dispatchFromDevtools: boolean
}

declare module '../vanilla' {
  interface StoreMutators<S, A> {
    'zustand/redux': WithRedux<S, A>
  }
}

type WithRedux<S, A> = Write<Cast<S, object>, StoreRedux<Cast<A, Action>>>

interface Action {
  type: unknown
}

interface StoreRedux<A extends Action> {
  dispatch: (a: A) => A
  dispatchFromDevtools: true
}

type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type Cast<T, U> = T extends U ? T : U

export const redux =
  <S extends State, A extends { type: unknown }>(
    reducer: (state: S, action: A) => S,
    initial: S
  ) =>
  (
    set: SetState<S & { dispatch: (a: A) => A }>,
    get: GetState<S & { dispatch: (a: A) => A }>,
    api: StoreApiWithRedux<S, A> & { devtools?: DevtoolsType }
  ): S & { dispatch: (a: A) => A } => {
    api.dispatch = (action: A) => {
      ;(set as NamedSet<S>)((state: S) => reducer(state, action), false, action)
      return action
    }
    api.dispatchFromDevtools = true

Review comment (suggestion):
actually, this one too. okay, i know it's just a preference, but prefer define things in advance whenever possible. (at least for me it's easier to read in my brain.)

Code after:
  init: (state: any) => void
  error: (payload: any) => void
}

/**
 * @deprecated Use `Mutate<StoreApi<T & { dispatch: (a: A) => A }>, [["zustand/redux", A]]>`.
 * See tests/middlewaresTypes.test.tsx for usage with multiple middlewares.
 */
export type StoreApiWithRedux<
  T extends State,
  A extends { type: unknown }
> = StoreApi<T & { dispatch: (a: A) => A }> & {
  dispatch: (a: A) => A
  dispatchFromDevtools: boolean
}

declare module '../vanilla' {
  interface StoreMutators<S, A> {
    'zustand/redux': WithRedux<S, A>
  }
}

interface StoreRedux<A extends Action> {
  dispatch: (a: A) => A
  dispatchFromDevtools: true
}

interface Action {
  type: unknown
}

type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type Cast<T, U> = T extends U ? T : U

type WithRedux<S, A> = Write<Cast<S, object>, StoreRedux<Cast<A, Action>>>

export const redux =
  <S extends State, A extends { type: unknown }>(
    reducer: (state: S, action: A) => S,
    initial: S
  ) =>
  (
    set: SetState<S & { dispatch: (a: A) => A }>,
    get: GetState<S & { dispatch: (a: A) => A }>,
    api: StoreApiWithRedux<S, A> & { devtools?: DevtoolsType }
  ): S & { dispatch: (a: A) => A } => {
    api.dispatch = (action: A) => {
      ;(set as NamedSet<S>)((state: S) => reducer(state, action), false, action)
      return action
    }
    api.dispatchFromDevtools = true
Repository: pmndrs/zustand
File: tests/context.test.tsx (TypeScript)

Code before:
      return { hasError: true }
    }
    render() {
      return this.state.hasError ? <div>errored</div> : this.props.children
    }
  }

  const { useStore } = createContext<CounterState>()
  function Component() {
    useStore()
    return <div>no error</div>
  }

  const { findByText } = render(
    <ErrorBoundary>
      <Component />
    </ErrorBoundary>
  )
  await findByText('errored')
})

it('useCallback with useStore infers types correctly', async () => {
  const { useStore } = createContext<CounterState>()
  function _Counter() {
    let x = useStore(useCallback((state) => state.count, []))
    expectAreTypesEqual<typeof x, number>().toBe(true)
  }
})

const expectAreTypesEqual = <A, B>() => ({
  toBe: (
    _: (<T>() => T extends B ? 1 : 0) extends <T>() => T extends A ? 1 : 0
      ? true
      : false
  ) => {},
})


Review comment (bug):
We have to use this because writing `x: number = useStore(..)` won't test the inference as even when the inference fails `x` will be inferred as `any` and it'll still compile.

Code after:
      return { hasError: true }
    }
    render() {
      return this.state.hasError ? <div>errored</div> : this.props.children
    }
  }

  const { useStore } = createContext<CounterState>()
  function Component() {
    useStore()
    return <div>no error</div>
  }

  const { findByText } = render(
    <ErrorBoundary>
      <Component />
    </ErrorBoundary>
  )
  await findByText('errored')
})

it('useCallback with useStore infers types correctly', async () => {
  const { useStore } = createContext<CounterState>()
  function _Counter() {
    const _x = useStore(useCallback((state) => state.count, []))
    expectAreTypesEqual<typeof _x, number>().toBe(true)
  }
})

const expectAreTypesEqual = <A, B>() => ({
  toBe: (
    _: (<T>() => T extends B ? 1 : 0) extends <T>() => T extends A ? 1 : 0
      ? true
      : false
  ) => {},
})
Repository: pmndrs/zustand
File: src/middleware/devtools.ts (TypeScript)

Code before:

declare module '../vanilla' {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  interface StoreMutators<S, A> {
    'zustand/devtools': WithDevtools<S>
  }
}

type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type Cast<T, U> = T extends U ? T : U

type WithDevtools<S> = Write<Cast<S, object>, StoreSetStateWithAction<S>> & {
  /**
   * @deprecated `devtools` property on the store is deprecated
   * it will be removed in the next major.
   * You shouldn't interact with the extension directly. But in case you still want to
   * you can patch `window.__REDUX_DEVTOOLS_EXTENSION__` directly
   */
  devtools?: DevtoolsType
}

type StoreSetStateWithAction<S> = S extends { getState: () => infer T }
  ? S & { setState: NamedSet<Cast<T, object>> }
  : never

interface DevtoolsOptions {
  name?: string
  anonymousActionType?: string
  serialize?:
    | boolean
    | {
        date?: boolean
        regex?: boolean
        undefined?: boolean
        nan?: boolean
        infinity?: boolean
        error?: boolean
        symbol?: boolean
        map?: boolean
        set?: boolean
      }
}

type DevtoolsType = {
  /**
   * @deprecated along with `api.devtools`, `api.devtools.prefix` is deprecated.
   * We no longer prefix the actions/names, because the `name` option already
   * creates a separate instance of devtools for each store.
   */
  prefix: string
  subscribe: (dispatch: any) => () => void

Review comment (suggestion):
See if we can use the exported `EnhancerOptions` type too (We'd also get the jsdoc for free). Something like...

```ts
interface DevtoolsOptions extends Pick<EnhancerOptions, "name" | "serialize"> {
  anonymousActionType?: string
}
```

Code after:
declare module '../vanilla' {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  interface StoreMutators<S, A> {
    'zustand/devtools': WithDevtools<S>
  }
}

// FIXME https://github.com/reduxjs/redux-devtools/issues/1097
type Message = {
  type: string
  payload?: any
  state?: any
}

type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type Cast<T, U> = T extends U ? T : U

type WithDevtools<S> = Write<Cast<S, object>, StoreSetStateWithAction<S>> & {
  /**
   * @deprecated `devtools` property on the store is deprecated
   * it will be removed in the next major.
   * You shouldn't interact with the extension directly. But in case you still want to
   * you can patch `window.__REDUX_DEVTOOLS_EXTENSION__` directly
   */
  devtools?: DevtoolsType
}

type StoreSetStateWithAction<S> = S extends { getState: () => infer T }
  ? S & { setState: NamedSet<Cast<T, object>> }
  : never

interface DevtoolsOptions {
  name?: string
  anonymousActionType?: string
  serialize?:
    | boolean
    | {
        date?: boolean
        regex?: boolean
        undefined?: boolean
        nan?: boolean
        infinity?: boolean
        error?: boolean
        symbol?: boolean
        map?: boolean
        set?: boolean
      }
}

type DevtoolsType = {
  /**
Repository: pmndrs/zustand
File: src/middleware/immer.ts (TypeScript)

Code before:
) => StateCreator<T, Mps, [['zustand/immer', never], ...Mcs]>

declare module '../vanilla' {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  interface StoreMutators<S, A> {
    ['zustand/immer']: WithImmer<S>
  }
}

type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type SkipTwo<T> = T extends []
  ? []
  : T extends [unknown]
  ? []
  : T extends [unknown?]
  ? []
  : T extends [unknown, unknown, ...infer A]
  ? A
  : T extends [unknown, unknown?, ...infer A]
  ? A
  : T extends [unknown?, unknown?, ...infer A]
  ? A
  : never

type WithImmer<S> = S extends {
  getState: () => infer T
  setState: infer SetState
}
  ? Write<
      S,
      SetState extends (...a: infer A) => infer Sr
        ? {
            setState(
              nextStateOrUpdater: T | Partial<T> | ((state: Draft<T>) => void),
              shouldReplace?: boolean | undefined,
              ...a: SkipTwo<A>
            ): Sr
          }
        : never
    >
  : never

type PopArgument<T extends (...a: never[]) => unknown> = T extends (
  ...a: [...infer A, infer _]
) => infer R
  ? (...a: A) => R
  : never

type ImmerImpl = <T extends State>(
  storeInitializer: PopArgument<StateCreator<T, [], []>>
) => PopArgument<StateCreator<T, [], []>>

Review comment (suggestion):
Hmm, I don't understand the trick here for better quickinfo...
It's now `extends` is two level. Okay, so many things to learn to be TS friendly.

Code after:
) => StateCreator<T, Mps, [['zustand/immer', never], ...Mcs]>

declare module '../vanilla' {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  interface StoreMutators<S, A> {
    ['zustand/immer']: WithImmer<S>
  }
}

type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type Cast<T, U> = T extends U ? T : U
type SkipTwo<T> = T extends []
  ? []
  : T extends [unknown]
  ? []
  : T extends [unknown?]
  ? []
  : T extends [unknown, unknown, ...infer A]
  ? A
  : T extends [unknown, unknown?, ...infer A]
  ? A
  : T extends [unknown?, unknown?, ...infer A]
  ? A
  : never

type WithImmer<S> = Write<Cast<S, object>, StoreImmer<S>>

type StoreImmer<S> = S extends {
  getState: () => infer T
  setState: infer SetState
}
  ? SetState extends (...a: infer A) => infer Sr
    ? {
        setState(
          nextStateOrUpdater: T | Partial<T> | ((state: Draft<T>) => void),
          shouldReplace?: boolean | undefined,
          ...a: SkipTwo<A>
        ): Sr
      }
    : never
  : never

type PopArgument<T extends (...a: never[]) => unknown> = T extends (
  ...a: [...infer A, infer _]
) => infer R
  ? (...a: A) => R
  : never

type ImmerImpl = <T extends State>(
  storeInitializer: PopArgument<StateCreator<T, [], []>>
) => PopArgument<StateCreator<T, [], []>>
Repository: pmndrs/zustand
File: src/react.ts (TypeScript)

Code before:
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'
import createStore, {
  EqualityChecker,
  Mutate,
  State,
  StateCreator,
  StateSelector,
  StoreApi,
  StoreMutatorIdentifier,
} from './vanilla'

export function useStore<S extends StoreApi<State>>(api: S): ExtractState<S>
export function useStore<S extends StoreApi<State>, U>(
  api: S,
  selector: StateSelector<ExtractState<S>, U>,
  equalityFn?: EqualityChecker<U>
): U
export function useStore<TState extends State, StateSlice>(
  api: StoreApi<TState>,
  selector: StateSelector<TState, StateSlice> = api.getState as any,
  equalityFn?: EqualityChecker<StateSlice>
) {
  const slice = useSyncExternalStoreWithSelector(
    api.subscribe,
    api.getState,
    // TODO avoid `any` and add type only in react.ts
    (api as any).getServerState || api.getState,
    selector,
    equalityFn
  )
  useDebugValue(slice)
  return slice
}

type ExtractState<S> = S extends { getState: () => infer T } ? T : never

export type UseBoundStore<S extends StoreApi<State>> = {
  (): ExtractState<S>
  <U>(
    selector: StateSelector<ExtractState<S>, U>,
    equals?: EqualityChecker<U>
  ): U
} & S

type Create = {
  <T extends State, Mos extends [StoreMutatorIdentifier, unknown][] = []>(
    initializer: StateCreator<T, [], Mos>
  ): UseBoundStore<Mutate<StoreApi<T>, Mos>>
  <T extends State>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(
    initializer: StateCreator<T, [], Mos>
  ) => UseBoundStore<Mutate<StoreApi<T>, Mos>>

Review comment (suggestion):
We simply allow specifying optional `getServerState` property. Note this has nothing to do with vanilla.ts.

Code after:
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'
import createStore, {
  EqualityChecker,
  Mutate,
  State,
  StateCreator,
  StateSelector,
  StoreApi,
  StoreMutatorIdentifier,
} from './vanilla'

type ExtractState<S> = S extends { getState: () => infer T } ? T : never

type WithReact<S extends StoreApi<State>> = S & {
  getServerState?: () => ExtractState<S>
}

export function useStore<S extends WithReact<StoreApi<State>>>(
  api: S
): ExtractState<S>

export function useStore<S extends WithReact<StoreApi<State>>, U>(
  api: S,
  selector: StateSelector<ExtractState<S>, U>,
  equalityFn?: EqualityChecker<U>
): U

export function useStore<TState extends State, StateSlice>(
  api: WithReact<StoreApi<TState>>,
  selector: StateSelector<TState, StateSlice> = api.getState as any,
  equalityFn?: EqualityChecker<StateSlice>
) {
  const slice = useSyncExternalStoreWithSelector(
    api.subscribe,
    api.getState,
    api.getServerState || api.getState,
    selector,
    equalityFn
  )
  useDebugValue(slice)
  return slice
}

export type UseBoundStore<S extends WithReact<StoreApi<State>>> = {
  (): ExtractState<S>
  <U>(
    selector: StateSelector<ExtractState<S>, U>,
    equals?: EqualityChecker<U>
  ): U
} & S
Repository: pmndrs/zustand
File: src/middleware/redux.ts (TypeScript)

Code before:
import { StateCreator, StoreMutatorIdentifier } from '../vanilla'
import { NamedSet } from './devtools'

type Write<T extends object, U extends object> = Omit<T, keyof U> & U
type Cast<T, U> = T extends U ? T : U

type Action = {
  type: unknown
}

type ReduxState<A extends Action> = {
  dispatch: StoreRedux<A>['dispatch']
}

type StoreRedux<A extends Action> = {
  dispatch: (a: A) => A
  dispatchFromDevtools: true
}

type WithRedux<S, A> = Write<Cast<S, object>, StoreRedux<Cast<A, Action>>>

type Redux = <
  T extends object,
  A extends Action,
  Cms extends [StoreMutatorIdentifier, unknown][] = []
>(
  reducer: (state: T, action: A) => T,
  initialState: T
) => StateCreator<Write<T, ReduxState<A>>, Cms, [['zustand/redux', A]]>

declare module '../vanilla' {
  interface StoreMutators<S, A> {
    'zustand/redux': WithRedux<S, A>
  }
}

type PopArgument<T extends (...a: never[]) => unknown> = T extends (
  ...a: [...infer A, infer _]
) => infer R
  ? (...a: A) => R
  : never


Review comment (suggestion):
@dai-shi Is removing the constraint in `A` intentional? This would allow non-redux actions (and non-redux reducers), which might not work well with `devtools`. I don't think it's a big deal to remove the constraint, but I'd prefer to keep it.

Code after:
import { StateCreator, StoreMutatorIdentifier } from '../vanilla'
import { NamedSet } from './devtools'

type Write<T, U> = Omit<T, keyof U> & U

type ReduxState<A> = {
  dispatch: StoreRedux<A>['dispatch']
}

type StoreRedux<A> = {
  dispatch: (a: A) => A
  dispatchFromDevtools: true
}

type WithRedux<S, A> = Write<S, StoreRedux<A>>

type Redux = <T, A, Cms extends [StoreMutatorIdentifier, unknown][] = []>(
  reducer: (state: T, action: A) => T,
  initialState: T
) => StateCreator<Write<T, ReduxState<A>>, Cms, [['zustand/redux', A]]>

declare module '../vanilla' {
  interface StoreMutators<S, A> {
    'zustand/redux': WithRedux<S, A>
  }
}

type PopArgument<T extends (...a: never[]) => unknown> = T extends (
  ...a: [...infer A, infer _]
) => infer R
  ? (...a: A) => R
  : never

type ReduxImpl = <T, A>(
  reducer: (state: T, action: A) => T,
  initialState: T
) => PopArgument<StateCreator<T & ReduxState<A>, [], []>>

const isObjectWithTypeProperty = (x: unknown): x is { type: unknown } =>
  x !== null && typeof x === 'object' && 'type' in x

const reduxImpl: ReduxImpl = (reducer, initial) => (set, _get, api) => {