如何基于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

