如何实现基于运行时布尔值的TypeScript条件返回类型?
解决useRouteQuery根据isArray参数返回对应类型的问题
问题核心是:希望useRouteQuery根据传入的isArray布尔值,精准返回LocationQueryValue或LocationQueryValue[]类型,但当前实现无论传true还是false,返回类型始终是联合类型LocationQueryValue | LocationQueryValue[]。
问题根源
原代码中泛型O定义为{ isArray?: boolean; clearPage?: boolean },导致options.isArray的类型被推断为boolean | undefined,而非具体的true或false字面量类型。QueryValue类型处理这个联合类型时,自然会输出联合结果。
解决方案
将isArray的类型单独提取为泛型参数,让TypeScript能精准推断其字面量类型,而非宽泛的boolean类型。修改后的代码如下:
type LocationQueryValue = string | null; declare function useRoute(): { query: Record<string, LocationQueryValue | LocationQueryValue[]> }; declare function computed<T>(fn: () => T): T; declare function toArray<T>(val: T | T[]): T[]; type QueryValue<IsArray extends boolean> = IsArray extends true ? LocationQueryValue[] : LocationQueryValue; export const useRouteQuery = < K extends string, IsArray extends boolean = false // 将isArray的类型单独作为泛型参数,默认值为false >( key: K, options: { isArray?: IsArray; clearPage?: boolean } ) => { const parsedOptions = { isArray: false as IsArray, // 断言类型匹配泛型IsArray clearPage: false, ...options }; const route = useRoute(); const getQueryValue = (): QueryValue<IsArray> => { const value = route.query[key]; // 此时parsedOptions.isArray的类型是IsArray,TypeScript能精准收窄分支类型 if (value && parsedOptions.isArray) { return toArray(value) as QueryValue<IsArray>; } return (value as LocationQueryValue) as QueryValue<IsArray>; }; const queryValue = computed(getQueryValue); return { queryValue }; }; // 测试用例:类型推断符合预期 const { queryValue: firstVal } = useRouteQuery("test", { isArray: true, clearPage: true }); // LocationQueryValue[] const { queryValue: secondVal } = useRouteQuery("test2", { isArray: false, clearPage: true }); // LocationQueryValue const { queryValue: thirdVal } = useRouteQuery("test3", {}); // LocationQueryValue(默认isArray为false)
关键修改点
- 泛型拆分:将
isArray的类型从O中剥离,单独作为IsArray泛型参数,指定其继承boolean并设置默认值false,让TypeScript能捕获传入的字面量类型(true或false)。 - 类型断言匹配:在
parsedOptions中把默认的isArray断言为IsArray,确保和泛型类型一致;getQueryValue的返回值也通过断言让TypeScript确认分支返回值符合QueryValue<IsArray>。 - 简化
QueryValue类型:直接基于IsArray的字面量类型判断,无需处理undefined(因为泛型默认值已经覆盖了未传isArray的场景)。
内容的提问来源于stack exchange,提问作者Arsen
相关产品推荐
相关产品推荐

