如何实现可返回类型化对象的React useTypedSearchParams Hook?
实现类型安全的React Hook:useTypedSearchParams
下面是满足需求的Hook实现,基于React Router v6的useSearchParams,能根据传入的泛型类型自动转换URL搜索参数的类型:
import { useSearchParams } from 'react-router-dom'; // 定义支持的基本类型 type SupportedPrimitive = string | number | boolean | null | undefined; // 映射目标类型,确保返回值与泛型定义一致 type TypedParams<T extends Record<string, SupportedPrimitive>> = { [K in keyof T]: T[K]; }; function useTypedSearchParams<T extends Record<string, SupportedPrimitive>>(): TypedParams<T> { const [searchParams] = useSearchParams(); const typedParams = {} as TypedParams<T>; // 遍历泛型定义的所有键,逐个转换参数 (Object.keys(typedParams) as Array<keyof T>).forEach((key) => { const rawValue = searchParams.get(key as string); // 参数不存在时,根据类型设置默认值/undefined if (rawValue === null) { typedParams[key] = undefined as unknown as T[keyof T]; return; } // 根据目标类型执行转换逻辑 switch (typeof typedParams[key]) { case 'number': typedParams[key] = parseInt(rawValue, 10) as unknown as T[keyof T]; break; case 'boolean': typedParams[key] = (rawValue === 'true') as unknown as T[keyof T]; break; default: typedParams[key] = rawValue as unknown as T[keyof T]; break; } }); return typedParams; }
核心实现说明
- 泛型约束:通过
T extends Record<string, SupportedPrimitive>限制传入的类型必须是键为字符串、值为基本类型的对象,确保类型安全。 - 类型映射:
TypedParams保证返回的对象结构和类型完全匹配你传入的泛型定义。 - 动态转换:遍历泛型的所有键,根据目标类型(
typeof typedParams[key])对URL原始参数值做转换:- 数字类型调用
parseInt(指定基数10避免八进制解析问题) - 布尔类型判断字符串是否为
'true' - 字符串类型直接返回原始值
- 数字类型调用
- 空值处理:如果URL中不存在对应参数,会设置为
undefined,你可以根据需求修改为默认值(比如数字设为0)。
使用示例
// 调用方式完全符合需求 const { id, slug } = useTypedSearchParams<{ id: number; slug: string }>(); // id 类型为number,slug类型为string
扩展建议
- 如果需要支持数组类型参数(比如
?tags=react&tags=typescript),可以扩展逻辑,用searchParams.getAll(key)获取所有值后批量转换。 - 可以添加参数验证逻辑,比如判断数字转换是否成功,避免
NaN的情况。
内容的提问来源于stack exchange,提问作者Littletime
相关产品推荐
相关产品推荐

