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

TypeScript中根据参数类型推导useSearchResults返回类型的问题

解决方案

要实现返回的state既符合Partial<SearchResultsState>,又能保留传入config.state的具体类型,核心是用泛型捕获初始状态的精确类型,同时兼容直接传值和函数式初始值的场景。

步骤1:定义基础类型和泛型约束

先明确基础状态接口,再为初始状态定义适配的泛型类型:

// 你的基础状态接口
interface SearchResultsState {
  a: number;
  b: string;
  c: boolean;
}

// 初始状态支持直接传Partial子类型,或返回该类型的函数
type InitialState<S extends Partial<SearchResultsState>> = S | (() => S);

步骤2:改造useSearchResults钩子

通过泛型S捕获传入初始状态的具体类型,返回类型合并S的精确类型与剩余属性的Partial类型:

import { useState } from 'react';

function useSearchResults<S extends Partial<SearchResultsState>>(
  config: { state: InitialState<S> }
): S & Omit<Partial<SearchResultsState>, keyof S> {
  // 初始化状态,用类型断言确保函数式初始值的类型被正确推断
  const [state, setState] = useState<S & Partial<SearchResultsState>>(
    config.state as S
  );

  // 这里添加钩子的核心逻辑(比如搜索结果处理、状态更新等)

  return state;
}

步骤3:验证效果

传入具体初始值时,返回的state会保留对应属性的精确类型,解决类型推断错误问题:

function test(a: number) {
  console.log(a);
}

// 传入{a:1},a会被推断为number而非number|undefined
const { a } = useSearchResults({ state: { a: 1 } });
test(a); // 不再报错

// 函数式初始值也能正常推断类型
const { b } = useSearchResults({ state: () => ({ b: "test" }) });
// b的类型为string

原理说明

  • 泛型S会精确捕获你传入的config.state的结构和类型,比如{a:1}会被捕获为{a: number}。
  • 返回类型S & Omit<Partial<SearchResultsState>, keyof S>:
    • 保留S中定义的属性的精确类型(比如a: number)
    • 对SearchResultsState中未在S里定义的属性,保持Partial的可选性(比如b: string | undefined)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:45:30