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

如何基于tRPC输出类型为React Native组件Props指定精确非可选类型?

问题解答

类型推断方式是否正确?

不正确。你当前用了RouterOutput['highline']['createHighline'],但你的查询是trpc.highline.getById.useQuery,对应的输出类型应该是RouterOutput['highline']['getById']——createHighline是创建接口的输出类型,和查询接口完全不匹配。

即便修正为RouterOutput['highline']['getById'],这个类型本身也是Highline | undefined:因为tRPC的useQuery返回的data类型继承了React Query的行为,初始加载阶段、查询失败时data都会是undefined,所以类型里会包含undefined。

如何将类型精确指定为Highline?

有几种可靠的方案:

1. 条件渲染确保导航时highline已存在

在触发导航前,通过条件判断排除undefined的情况,TypeScript会自动缩小类型:

// 只有当highline存在时才渲染导航按钮
{highline && (
  <TouchableOpacity onPress={() => navigation.navigate('Details', { highline })}>
    <Text>查看详情</Text>
  </TouchableOpacity>
)}

此时传入详情页的highline类型会被推断为Highline,无需额外标注。

2. 使用tRPC的useSuspenseQuery

tRPC支持React Suspense,改用useSuspenseQuery后,查询会自动等待数据加载完成,返回的data不会是undefined:

const { data: highline } = trpc.highline.getById.useSuspenseQuery(highlitedMarker.id);

这种情况下highline的类型就是Highline,直接传递即可。注意需要在组件树上层添加<Suspense>组件处理加载状态。

3. 手动缩小类型(非空断言,谨慎使用)

如果你能100%确定highline在导航时一定存在(比如通过isFetchedAfterMount判断查询已完成),可以用非空断言强制去除undefined:

navigation.navigate('Details', { highline: highline! });

但这种方式不推荐,一旦逻辑出现问题(比如查询失败),会导致运行时错误。

4. 在详情页Props中处理

如果无法避免传递undefined,可以在详情页的Props类型中先接收Highline | undefined,然后在组件内部用类型守卫确保后续使用的是Highline:

// 详情页Props类型
type DetailsScreenProps = {
  route: {
    params: {
      highline: Highline | undefined;
    };
  };
};

// 组件内部处理
const DetailsScreen = ({ route }: DetailsScreenProps) => {
  const { highline } = route.params;
  if (!highline) {
    return <Text>数据加载失败</Text>;
  }
  // 此处highline类型已缩小为Highline
  return <Text>{highline.name}</Text>;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:52:09