Repository: pmndrs/zustand
File: src/index.ts (TypeScript)

Code before:
import { useCallback, useLayoutEffect, useReducer, useRef } from 'react'
import shallowEqual from './shallowEqual'

export type StateListener<T> = (state: T) => void
export type StateSelector<T, U> = (state: T) => U
export type PartialState<T> = Partial<T> | ((state: T) => Partial<T>)

export type State = Record<string, any>
export type SetState<T> = (partialState: PartialState<T>) => void
export type GetState<T> = () => T

export type UseStore<T> = <U = T>(selector?: StateSelector<T, U>) => U

export interface StoreApi<T> {
  getState: GetState<T>
  setState: SetState<T>
  subscribe: (listener: StateListener<T>) => () => void
  destroy: () => void
}

const reducer = <T>(state: any, newState: T) => newState

export default function create<
  TState extends State,
  TSetState extends SetState<TState> = SetState<TState>,
  TGetState extends GetState<TState> = GetState<TState>
>(
  createState: (set: TSetState, get: TGetState) => TState
): [UseStore<TState>, StoreApi<TState>] {
  const listeners: Set<StateListener<TState>> = new Set()

  const setState = (partialState: PartialState<TState>) => {
    state = Object.assign(
      {},
      state,
      typeof partialState === 'function' ? partialState(state) : partialState
    )
    listeners.forEach(listener => listener(state))
  }

  const getState = () => state

  const subscribe = (listener: StateListener<TState>) => {
    listeners.add(listener)
    return () => {
      listeners.delete(listener)
    }
  }

  const destroy = () => {

Review comment (refactor):
These `TSetState` and `TGetState` generics should just be removed. I was trying to use them to generate correct function signatures of the `set` and `get` functions passed into `createState`. I couldn’t get it to work though so we can simplify this bit by removing them:
```ts
export default function create<TState extends State>(
  createState: (set: SetState<State>, get: GetState<State>) => TState
): [UseStore<TState>, StoreApi<TState>] {
```

Code after:
import { useCallback, useLayoutEffect, useReducer, useRef } from 'react'
import shallowEqual from './shallowEqual'

export type StateListener<T> = (state: T) => void
export type StateSelector<T, U> = (state: T) => U
export type PartialState<T> = Partial<T> | ((state: T) => Partial<T>)

export type State = Record<string, any>
export type SetState<T> = (partialState: PartialState<T>) => void
export type GetState<T> = () => T

export type UseStore<T> = {
  (): T
  <U>(selector: StateSelector<T, U>, dependencies?: ReadonlyArray<any>): U
}

export interface StoreApi<T> {
  getState: GetState<T>
  setState: SetState<T>
  subscribe: (listener: StateListener<T>) => () => void
  destroy: () => void
}

const reducer = <T>(state: any, newState: T) => newState

export default function create<TState extends State>(
  createState: (set: SetState<State>, get: GetState<State>) => TState
): [UseStore<TState>, StoreApi<TState>] {
  const listeners: Set<StateListener<TState>> = new Set()

  const setState = (partialState: PartialState<TState>) => {
    state = Object.assign(
      {},
      state,
      typeof partialState === 'function' ? partialState(state) : partialState
    )
    listeners.forEach(listener => listener(state))
  }

  const getState = () => state

  const subscribe = (listener: StateListener<TState>) => {
    listeners.add(listener)
    return () => {
      listeners.delete(listener)
    }
  }

  const destroy = () => {
    listeners.clear()