TanStack Router中处理非标准数组返回类型的最佳实践
2025-05-24 09:22:51作者:劳婵绚Shirley
在TanStack Router项目中,开发者在使用createServerFn创建服务端函数时,可能会遇到一个常见的类型检查问题——当尝试返回带有额外属性的非标准数组时,TypeScript会报类型错误。本文将深入分析这一问题产生的原因,并提供几种实用的解决方案。
问题背景
在开发过程中,我们经常会使用像Ronin这样的数据查询库,这些库有时会返回带有分页信息的特殊数组结构。例如:
const posts = await get.posts(); // 返回Array<Post> & { moreAfter: string; moreBefore: string }
当开发者尝试在createServerFn中直接返回这种特殊数组时,会遇到类型错误,因为TanStack Router默认期望返回的是标准的JSON可序列化类型。
问题本质
这个问题的核心在于JSON序列化的限制。JSON规范中数组只能是纯数组,不能带有额外属性。当服务端函数返回带有额外属性的数组时,这些属性在序列化为JSON传输到客户端的过程中会丢失。
解决方案
1. 解构重组法
最直接的方法是将数组和额外属性分开处理:
export const $getPosts = createServerFn({
method: "GET",
}).handler(async () => {
const posts = await get.posts();
return {
records: [...posts], // 展开为纯数组
moreBefore: posts.moreBefore,
moreAfter: posts.moreAfter
};
});
2. 类型断言法
如果你确定只需要数组部分数据,可以使用类型断言:
export const $getPosts = createServerFn({
method: "GET",
}).handler(async () => {
const posts = await get.posts();
return {
posts: posts as Post[], // 明确告诉TypeScript我们只需要数组部分
pagination: {
before: posts.moreBefore,
after: posts.moreAfter
}
};
});
3. 创建通用工具函数
对于项目中频繁使用的情况,可以创建一个通用的序列化工具函数:
type PaginatedArray<T> = ReadonlyArray<T> & {
moreBefore?: string | null;
moreAfter?: string | null;
};
function serializePaginated<T>(data: PaginatedArray<T>) {
return {
records: [...data],
pagination: {
before: data.moreBefore,
after: data.moreAfter
}
};
}
// 使用示例
export const $getPosts = createServerFn({
method: "GET",
}).handler(async () => {
const posts = await get.posts();
return serializePaginated(posts);
});
最佳实践建议
-
明确数据需求:在服务端函数中,明确你需要传输哪些数据给客户端,避免传输不必要的信息。
-
保持类型安全:虽然可以使用类型断言,但要确保你确实了解数据结构和序列化行为。
-
文档记录:对于特殊的数据结构转换,添加适当的代码注释说明转换原因和预期行为。
-
考虑性能:对于大型数组,展开操作(
...)可能会有性能影响,需要权衡可维护性和性能。
通过以上方法,开发者可以优雅地解决TanStack Router中非标准数组返回的类型问题,同时确保数据的正确序列化和传输。
登录后查看全文
热门项目推荐
相关项目推荐
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust099- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
MiMo-V2.5-ProMiMo-V2.5-Pro作为旗舰模型,擅⻓处理复杂Agent任务,单次任务可完成近千次⼯具调⽤与⼗余轮上 下⽂压缩。Python00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
Kimi-K2.6Kimi K2.6 是一款开源的原生多模态智能体模型,在长程编码、编码驱动设计、主动自主执行以及群体任务编排等实用能力方面实现了显著提升。Python00
MiniMax-M2.7MiniMax-M2.7 是我们首个深度参与自身进化过程的模型。M2.7 具备构建复杂智能体应用框架的能力,能够借助智能体团队、复杂技能以及动态工具搜索,完成高度精细的生产力任务。Python00
项目优选
收起
deepin linux kernel
C
28
16
Claude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed.
Get Started
Rust
570
99
暂无描述
Dockerfile
709
4.51 K
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
958
955
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.61 K
942
Ascend Extension for PyTorch
Python
572
694
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
413
339
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
1.42 K
116
暂无简介
Dart
951
235
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
12
2