"函数的x实例"和"x的类型==="函数"有什么区别



我想在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;
}

我如何在getStoredValue函数中检查initialValue的类型

如果我使用initialValue instanceof Function,它可以

但如果我使用typeof initialValue === "function",我会在initialValue()下得到红色下划线,上面写着:

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

我认为使用typeof更好,但为什么我从typescript 收到这样的消息

通常的情况确实是typeof ___ === "function"。我认为问题是T是完全不受约束的,这意味着InitialValue可以实例化,T函数(这就是为什么我们在错误消息中看到(() => T) | (T & Function)(。

如果您更新InitialValue以预期T将不是一个函数,则您的typeof initialValue === "function"检查将按您的预期工作:

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

游乐场链接

最新更新