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

Jest测试中tRPC useQuery参数类型不匹配问题求助

问题原因及解决方案

核心原因

  1. Mock数据类型不匹配:测试中返回的mock数据没有严格遵循tRPC路由定义的返回类型,比如仅返回{ id: string }缺少路由中定义的devices等其他字段,导致TypeScript类型校验失败。
  2. Mock的tRPC客户端丢失类型:手动mock trpc.useQuery时,没有继承原tRPC路由的类型定义,导致TypeScript无法识别返回数据的结构(如user.devices)。
  3. Monorepo类型解析问题:monorepo中tRPC的类型文件路径未被正确配置,测试环境无法读取到路由定义的类型信息。

解决方案

1. 用tRPC生成的类型约束Mock数据

从tRPC路由定义中导出自动生成的返回类型,用它来约束mock数据,确保结构完全匹配:

// 导入tRPC路由生成的输出类型
import type { RouterOutputs } from '@/server/trpc/router';

// 定义完全符合类型的mock用户数据
const mockUser: RouterOutputs['user']['get'] = {
  id: 'user-123',
  devices: [{ id: 'device-001', model: 'iPhone 15' }],
  // 补充路由定义中所有必填字段
};

2. 正确Mock tRPC客户端并保留类型

方式一:使用tRPC官方测试工具

利用@trpc/react-query提供的测试能力,创建带类型的mock客户端:

import { createTRPCReact } from '@trpc/react-query';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { render } from '@testing-library/react-native';
import type { Router } from '@/server/trpc/router';

// 创建带路由类型的tRPC实例
const trpc = createTRPCReact<Router>();

// 构造mock客户端
const mockTRPCClient = trpc.createClient({
  links: [
    () => ({
      async op() {
        return { data: mockUser }; // 使用符合类型的mock数据
      },
    }),
  ],
});

// 在测试中用mock客户端包裹组件
test('显示用户设备列表', async () => {
  const queryClient = new QueryClient();
  render(
    <trpc.Provider client={mockTRPCClient} queryClient={queryClient}>
      <UserDeviceComponent />
    </trpc.Provider>
  );
  // 执行测试断言逻辑
});

方式二:手动Mock时保留类型

如果手动mock useQuery,确保返回的数据类型与路由输出一致:

// 假设你的tRPC实例导出在@/utils/trpc
jest.mock('@/utils/trpc', () => ({
  useQuery: jest.fn(() => ({
    data: mockUser, // 用符合RouterOutputs类型的mock数据
    isLoading: false,
    error: null,
  })),
}));

3. 修复Monorepo类型配置

检查React Native包的tsconfig.json,确保tRPC路由所在的目录被包含在类型解析范围内:

{
  "include": [
    "src/**/*",
    "../server/trpc/**/*" // 假设server包在monorepo的同级目录
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/server/*": ["../server/*"] // 配置路径别名,确保类型能被正确解析
    }
  }
}

4. 安全替代ts-ignore的方式

如果需要临时调整类型,使用类型断言而非// @ts-ignore,明确告知TypeScript数据的真实类型:

const { data: user } = trpc.useQuery(['user.get']);
// 用路由输出类型断言,替代ts-ignore
const devices = (user as RouterOutputs['user']['get']).devices;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:15:33