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

解决TypeScript函数基于第二个可选参数的第一个参数类型推导问题

解决方案

问题根源在于原类型定义中,泛型Selected会被update参数的类型自动推断。当传入异步更新函数时,Selected会被推断为Promise<number>,但选择器函数返回的是原始number类型,导致类型不兼容。

修改类型定义(使用函数重载)

通过函数重载明确每种更新方式对应的类型约束,确保选择器始终返回原始状态类型,而非Promise:

type NestedStateSetter<State> = {
    <Selected = State>(update: Selected, selector?: (state: State) => Selected): Promise<Selected>;
    <Selected = State>(update: () => Selected, selector?: (state: State) => Selected): Promise<Selected>;
    <Selected = State>(update: () => Promise<Selected>, selector?: (state: State) => Selected): Promise<Selected>;
};

const initialState = {
    a: {
        b: {
            c: 0,
        },
    },
};

const setState: NestedStateSetter<typeof initialState> = (update, selector) => {
    throw "Yeet";
};

setState(1, (state) => state.a.b.c) // Ok
setState(() => 2, (state) => state.a.b.c) // Ok
setState(async () => 5, (state) => state.a.b.c) // Now Ok

原理说明

函数重载分别定义了三种更新场景的类型:

  • 直接传入值:update为Selected类型,选择器返回Selected
  • 同步更新函数:update返回Selected,选择器返回Selected
  • 异步更新函数:update返回Promise<Selected>,选择器仍返回Selected

这样TypeScript会正确推断Selected为选择器返回的原始类型(如示例中的number),而非异步函数返回的Promise类型,解决了类型不匹配问题,同时避免了柯里化带来的破坏性变更。

内容的提问来源于stack exchange,提问作者Gabriel Pureliani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:42:44