You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:12:50