Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading