TypeScript报错:类型成员并非全部可调用,已做function检查仍报错
TypeScript实现类React数据仓库的调用类型报错解决
我尝试用TypeScript实现一个类React的简易数据仓库,支持传入函数获取旧仓库值并返回新值,但在setStore函数中调用newStore(store)时出现报错:
This expression is not callable.
Not all constituents of type '((store: T) => T) | (T & Function)' are callable.
Type 'T & Function' has no call signatures.
我已经通过typeof检查newStore是function,但TypeScript仍无法推断它是可调用类型,相关代码如下:
type TReturned<T> = [ () => T, (newStore: T | ((store: T) => T)) => void, ] function createDataStore<T>(store: T) : TReturned<T> { function getStore() { return store } function setStore(newStore: T | ((store: T) => T)) { // 报错位置 store = typeof newStore === 'function' ? newStore(store) : newStore } return [getStore, setStore] } const [getCount, setCount] = createDataStore<number>(1) setCount((store: number) => { return store + 1 }) console.log(getCount())
问题原因
核心问题在于TypeScript无法区分T本身可能是函数类型的场景,导致联合类型T | ((store: T) => T)出现模糊性。比如当T是任意函数类型时,T & Function会被保留,但这类类型没有明确的(store: T) => T调用签名,所以TypeScript认为调用不安全。
解决方法
通过类型谓词明确判断传入的是更新函数,消除类型模糊性:
type TReturned<T> = [ () => T, (newStore: T | ((store: T) => T)) => void, ] function createDataStore<T>(store: T): TReturned<T> { function getStore() { return store } // 定义类型谓词,明确标记符合条件的为更新函数类型 function isUpdater(newStore: T | ((store: T) => T)): newStore is (store: T) => T { return typeof newStore === 'function'; } function setStore(newStore: T | ((store: T) => T)) { store = isUpdater(newStore) ? newStore(store) : newStore } return [getStore, setStore] } const [getCount, setCount] = createDataStore<number>(1) setCount((store: number) => store + 1) console.log(getCount()) // 输出2
类型谓词isUpdater会在运行时检查类型后,告诉TypeScript:符合typeof newStore === 'function'条件的变量,就是(store: T) => T类型,从而安全调用。
内容的提问来源于stack exchange,提问作者user3331344
相关产品推荐
相关产品推荐

