You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何传递Remix useLoaderData返回的JsonifyObject<T>并解决类型错误

解决Remix 2.9.2中JsonifyObject类型兼容问题

自定义Jsonify类型替代未导出的内部类型

Remix的JsonifyObject是未对外导出的内部类型,无法直接导入。你可以自己实现一个逻辑完全一致的Jsonify类型,用来描述序列化后的数据结构:

type Jsonify<T> = T extends Date
  ? string // Date对象序列化后会变成ISO格式字符串
  : T extends object
  ? { [K in keyof T]: Jsonify<T[K]> } // 递归处理嵌套对象
  : T extends undefined | null | boolean | number | string
  ? T // 基础类型保持原类型
  : never;

之后你可以用这个类型约束useLoaderData的返回值,或者直接调整formatIdAndDate的参数类型为Jsonify<IdAndDate>,这样既不会丢失date为字符串的类型提示,也能通过TypeScript检查:

// 调整格式化函数的参数类型
function formatIdAndDate(data: Jsonify<IdAndDate>) {
  // 此时data.date类型明确为string,直接转换为Date处理
  const formattedDate = new Date(data.date).toLocaleString();
  return `${data.id}: ${formattedDate}`;
}

// 组件中直接使用,无需类型断言
const data = useLoaderData<typeof loader>() as Jsonify<IdAndDate>;
formatIdAndDate(data);

让格式化函数兼容原始与序列化两种类型

如果需要formatIdAndDate同时支持服务端的原始IdAndDate类型和客户端的序列化后类型,可以将参数设为联合类型,并在内部做类型判断:

function formatIdAndDate(data: IdAndDate | Jsonify<IdAndDate>) {
  // 统一处理date:如果是字符串则转为Date,否则直接使用
  const targetDate = typeof data.date === 'string' ? new Date(data.date) : data.date;
  return `${data.id} - ${targetDate.toLocaleDateString('zh-CN')}`;
}

// 组件中直接传入useLoaderData返回值,无类型错误
const data = useLoaderData<typeof loader>();
formatIdAndDate(data);

使用类型守卫做安全类型校验

如果不想修改格式化函数,也可以通过类型守卫来确认数据结构,确保类型安全的同时保留类型提示:

// 定义类型守卫,校验数据是否为序列化后的IdAndDate
function isJsonifiedIdAndDate(data: unknown): data is Jsonify<IdAndDate> {
  return (
    typeof data === 'object' &&
    data !== null &&
    'id' in data &&
    typeof (data as any).id === 'string' &&
    'date' in data &&
    typeof (data as any).date === 'string'
  );
}

// 组件中使用
const data = useLoaderData<typeof loader>();
if (isJsonifiedIdAndDate(data)) {
  // 此处data类型被正确推断为Jsonify<IdAndDate>,可安全传入格式化函数
  formatIdAndDate(data as IdAndDate); // 若函数未修改参数类型,此处断言安全且保留类型提示
}

内容的提问来源于stack exchange,提问作者rickjoi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:40:25