我想在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);
游乐场链接