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

Code before:
    listeners.forEach(listener => listener(state))
  }

  const getState = () => state

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

  const destroy = () => {
    listeners.clear()
    state = {} as TState
  }

  function useStore(): TState
  function useStore<U>(
    selector: StateSelector<TState, U>,
    dependencies?: ReadonlyArray<any>
  ): U
  function useStore<U>(
    selector?: StateSelector<TState, U>,
    dependencies?: ReadonlyArray<any>
  ) {
    // State selector gets entire state if no selector was passed in
    const stateSelector = typeof selector === 'function' ? selector : getState
    const selectState = useCallback(
      stateSelector,
      dependencies as ReadonlyArray<any>
    )
    const selectStateRef = useRef(selectState)
    let [stateSlice, dispatch] = useReducer(reducer, state, selectState)

    // Call new selector if it has changed
    if (selectState !== selectStateRef.current) stateSlice = selectState(state)

    // Store in ref to enable updating without rerunning subscribe/unsubscribe
    const stateSliceRef = useRef(stateSlice)

    // Update refs only after view has been updated
    useLayoutEffect(() => {
      selectStateRef.current = selectState
      stateSliceRef.current = stateSlice
    }, [selectState, stateSlice])

    // Subscribe/unsubscribe to the store only on mount/unmount
    useLayoutEffect(() => {
      return subscribe(() => {
        // Use the last selector passed to useStore to get current state slice

Review comment (suggestion):
We should add a return type to useStore: `TState | U`.

Code after:
  }

  const getState = () => state

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

  const destroy = () => {
    listeners.clear()
    state = {} as TState
  }

  function useStore(): TState
  function useStore<U>(
    selector: StateSelector<TState, U>,
    dependencies?: ReadonlyArray<any>
  ): U
  function useStore<U>(
    selector?: StateSelector<TState, U>,
    dependencies?: ReadonlyArray<any>
  ): TState | U {
    // State selector gets entire state if no selector was passed in
    const stateSelector = typeof selector === 'function' ? selector : getState
    const selectState = useCallback(
      stateSelector,
      dependencies as ReadonlyArray<any>
    )
    const selectStateRef = useRef(selectState)
    let [stateSlice, dispatch] = useReducer(reducer, state, selectState)

    // Call new selector if it has changed
    if (selectState !== selectStateRef.current) stateSlice = selectState(state)

    // Store in ref to enable updating without rerunning subscribe/unsubscribe
    const stateSliceRef = useRef(stateSlice)

    // Update refs only after view has been updated
    useLayoutEffect(() => {
      selectStateRef.current = selectState
      stateSliceRef.current = stateSlice
    }, [selectState, stateSlice])

    // Subscribe/unsubscribe to the store only on mount/unmount
    useLayoutEffect(() => {
      return subscribe(() => {
        // Use the last selector passed to useStore to get current state slice
        const selectedSlice = selectStateRef.current(state)