我正在定义一个与React的useState:具有相同签名的函数
declare function useState<S>(
initialState: S | (() => S),
): [S, React.Dispatch<React.SetStateAction<S>>];
以下是部分功能:
function foo<T>(initialState: T | (() => T)) {
typeof initialState === 'function' ? initialState() : initialState;
}
我得到这个错误:
This expression is not callable.
Not all constituents of type '(() => T) | (T & Function)' are callable.
Type 'T & Function' has no call signatures.(2349)
T & Function
不意味着T
是一个函数,所以它是可调用的吗?如何在不强制类型转换的情况下修复此问题?
使用initialState instanceof Function
:可以成功缩小类型
function foo<T>(initialState: T | (() => T)) {
initialState instanceof Function ? initialState() : initialState;
}
编辑:有趣的是,这会编译,但在某些边缘情况下会失败。例如,如果initialState
是Object.create(Function.prototype)
。这是Function
的一个实例,但不可调用。
当typeof initialState
是'function'
时,最简单的方法是告诉编译器initialState
是一个函数。
function foo<T>(initialState: T | (() => T)) {
if (isFunction(initialState)) {
initialState();
} else {
initialState;
}
}
function isFunction<T>(f: T | (() => T)): f is (() => T) {
return typeof f === 'function';
}