Home > Net >  What is the difference between `x instanceof Function` and `typeof x === 'function`
What is the difference between `x instanceof Function` and `typeof x === 'function`

Time:08-21

I want to create this hook in React (ts)

import { useState, useDeferredValue, useEffect } from "react";

type InitialValue<T> = T | (() => T);

function getStoredValue<T>(key: string, initialValue: InitialValue<T>) {
  const savedValue = localStorage.getItem(key);
  if (savedValue) return JSON.parse(savedValue) as T;
  // return initialValue instanceof Function ? initialValue() : initialValue;
  return typeof initialValue === "function" ? initialValue() : initialValue;
}

export default function useLocalStorage<T>(key: string, _default_value: InitialValue<T>) {
  const [value, setValue] = useState(() => getStoredValue(key, _default_value));

  const deferredValue = useDeferredValue(value);

  useEffect(() => {
    if (deferredValue) localStorage.setItem(key, JSON.stringify(deferredValue));
    console.log("saved");
  }, [deferredValue]);

  return [value, setValue] as const;
}

how can i check for the type of initialValue in getStoredValue function

if i use initialValue instanceof Function it works

but if i use typeof initialValue === "function" i get this red-underline under initialValue() that says:

This expression is not callable.
  Not all constituents of type '(() => T) | (T & Function)' are callable.
    Type 'T & Function' has no call signatures.ts(2349)

i think to use typeof is better but why i get such a message from typescript

CodePudding user response:

The usual thing is indeed typeof ___ === "function". I think the problem is that T is completely unconstrained, which means that InitialValue can be instantiated with T being a function (which is why we see (() => T) | (T & Function) in the error message).

If you update InitialValue to expect that T will not be a function, your typeof initialValue === "function" check works as you expect:

type InitialValue<T> = T extends Function ? never : T | (() => T);

Playground link

  • Related