如何在同一函数中处理分页与非分页请求结果的类型?
解决API返回分页/非分页数据的TypeScript类型推断问题
你的问题核心是TypeScript无法根据paginate参数自动关联返回值的类型,导致访问分页数据的data属性时报错。下面提供两种可行的解决方案:
方案一:使用类型守卫缩小类型范围
先定义一个类型守卫函数,用来判断返回结果是否为分页数据类型:
interface PaginatedWorkflow { meta: Record<string, unknown>; data: Workflow[]; } // 类型守卫函数 function isPaginatedWorkflow(result: Workflow[] | PaginatedWorkflow): result is PaginatedWorkflow { return typeof result === 'object' && result !== null && 'data' in result; }
然后在调用useGetWorkflows时,用这个守卫确认类型:
async getWorkflows( paginate: boolean, search: string, sort: string, order: string, page: number, size: number ) { const { data, pending, refresh, error } = await useGetWorkflows(paginate, search, sort, order, page, size); const responseData = data?.value; if (paginate) { // 通过类型守卫确保responseData是分页类型 this.workflows = responseData && isPaginatedWorkflow(responseData) ? responseData.data : []; } else { this.workflows = Array.isArray(responseData) ? responseData : []; } if (error.value) { useNegativeNotify("Error retrieving workflows: " + error.value); } }
方案二:使用函数重载关联参数与返回类型
通过函数重载,让TypeScript根据paginate的布尔值直接推断返回类型:
interface PaginatedWorkflow { meta: Record<string, unknown>; data: Workflow[]; } // 定义函数重载签名 export function useGetWorkflows(paginate: true, search: string, sort: string, order: string, page: number, size: number): ReturnType<typeof useFetch<PaginatedWorkflow>>; export function useGetWorkflows(paginate: false, search: string, sort: string, order: string, page: number, size: number): ReturnType<typeof useFetch<Workflow[]>>; // 实现函数 export function useGetWorkflows( paginate: boolean, search: string, sort: string, order: string, page: number, size: number ) { return useFetch(uri, { method: "GET", baseURL: runtimeConfig.public.apiBaseURL, headers: { "Content-Type": "application/json", }, params: { paginate, search, sort, order, page, size, }, }) as typeof paginate extends true ? ReturnType<typeof useFetch<PaginatedWorkflow>> : ReturnType<typeof useFetch<Workflow[]>>; }
这样调用时,当你传入paginate: true,TypeScript会自动推断返回的data.value是PaginatedWorkflow类型,直接访问data属性不会再报错。
额外优化点
- 接口名改为大驼峰
PaginatedWorkflow,符合TypeScript代码规范; - 将
meta: {}改为meta: Record<string, unknown>,避免空对象类型过于宽泛。
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

