React Typescript Generic Type Overloading (e.g. useState)

I am attempting to create an overloaded function that will write to and from session storage instead of the standard state. I’d like it to be overloadable in the instances where I only provide a type and not an initial value. Exactly like what useState does in react.

Here is what I have so far:

export function useSessionState<S = undefined>(initialState?: S): [S, (state: S) => void];
export function useSessionState<S>(initialState: S): [S, (state: S) => void] {
  const [state, setState] = useState<S>()

  // Unimportant: Do something to load to and from session storage.

  return [state, (value) => {

  }]
}

When I try to consume this type I only ever get the result type of one of the overloads.

// Variable 'state' is a string as expected.
const [state, setState] = useSessionState("some_initial_value")

// Variable 'undefinedState' is also a string, but it should be undefined since no 'initialState' was provided.
const [undefinedState, setUndefinedState] = useSessionState<string>()

12 thoughts on “React Typescript Generic Type Overloading (e.g. useState)”

Leave a Comment