Skip to main content

TypeScript

React Query 现在是用TypeScript写的,以确保库和项目里有关的代码是类型安全的!

需要记住的是:

  • 目前需要使用 TypeScript v4.1 或更高版本
  • 对该库中的类型所做的更改被认为是非破坏性(non-breaking)的,并且通常以补丁(小版本号)的形式发布(每次类型的增强都会在主要版本中!)。
  • 强烈建议您react-query包版本锁定在一个特定的小版本号上,并做好在任何版本之间类型都会固定或升级的打算
  • 与类型无关的公共 API 仍然非常严格地遵循 semver 版本守则。

类型推导

React Query 中的类型通常可以很好地被 ts 自动推导,因此你不需要自己来提供类型注释

const { data } = useQuery({
// ^? const data: number | undefined
queryKey: ["test"],
queryFn: () => Promise.resolve(5),
});

typescript playground

const { data } = useQuery({
// ^? const data: string | undefined
queryKey: ["test"],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
});

typescript playground

如果 queryFn 有一个定义良好的返回类型,那么这种方法最有效。 请记住,大多数的数据获取库都会默认返回一个any类型来填充,所以请确保将其提取到一个拥有正确类型的函数:

const fetchGroups = (): Promise<Group[]> =>
axios.get("/groups").then((response) => response.data);

const { data } = useQuery({ queryKey: ["groups"], queryFn: fetchGroups });
// ^? const data: Group[] | undefined

typescript playground

类型窄化

React Query 对查询结果使用可辨识的联合类型(discriminated union type),其由status字段和派生的布尔状态字段区分。例如下面的示例,用success的相关状态来确保data是已被定义和赋值:

const { data, isSuccess } = useQuery({
queryKey: ["test"],
queryFn: () => Promise.resolve(5),
});

if (isSuccess) {
data;
// ^? const data: number
}

typescript playground

错误字段的类型

error 的类型默认是unknown。 这和 TypeScript 在 catch 语句中给出的默认值一致(请看useUnknownInCatchVariables)。 处理error最安全的方法是在运行时进行检查;或者是显式地定义dataerror的类型:

const { error } = useQuery({ queryKey: ["groups"], queryFn: fetchGroups });
// ^? const error: unknown

if (error instanceof Error) {
error;
// ^? const error: Error
}

typescript playground

const { error } = useQuery<Group[], Error>(["groups"], fetchGroups);
// ^? const error: Error | null

typescript playground

延伸阅读

关于在 Typescript 中类型推断的技巧和建议,请参阅此社区资源。 要了解如何做到尽可能好的类型安全,你可以阅读Type-safe React Query