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
相关产品推荐
相关产品推荐

