RTK Query结合GraphQL使用时如何实现类型安全及配置baseQuery
问题解答
一、类型安全相关问题
- 仅手动标注
builder.query<Device, void>这类泛型,只能实现有限的类型安全:仅能约束你调用RTK Query生成的业务钩子时的出入参格式,无法校验你编写的GraphQL查询语句和服务端Schema、实际返回值的匹配性。如果你的查询语句里漏写了字段、参数类型写错,TypeScript不会给出任何提前提示,很容易出现运行时报错、类型定义和实际返回不一致的问题。 - 完整的类型安全必须配合GraphQL Code Generator实现:它会基于服务端Schema和你写的GraphQL查询语句自动生成对应的类型定义、请求方法,能从查询语句编写到调用返回全链路校验类型一致性,不会出现类型和实际数据脱节的情况。
二、基于graphql-request生成SDK的baseQuery实现
你之前的思路方向是对的,但需要适配RTK Query要求的baseQuery入参规范,正确的实现如下:
首先完成GraphQL Code Generator的配置,生成和graphql-request适配的SDK文件,之后按下面的方式编写baseQuery和API定义:
import { createApi } from '@reduxjs/toolkit/query/react' import { GraphQLClient } from 'graphql-request' import { getSdk, Sdk } from './sdk' // 导入自动生成的SDK类型和实例方法 // 初始化GraphQL请求客户端 const client = new GraphQLClient('https://countries.trevorblades.com/') const sdk = getSdk(client) // 符合RTK Query规范的GraphQL baseQuery const graphqlBaseQuery = async <T extends keyof Sdk>( args: { operation: T; variables?: Parameters<Sdk[T]>[0] } ) => { try { const result = await sdk[args.operation](args.variables) return { data: result } } catch (error) { // 统一格式化错误返回,适配RTK Query的错误处理逻辑 return { error: { status: (error as any)?.response?.status || 500, data: error } } } } // 创建业务API实例 export const api = createApi({ reducerPath: 'graphqlApi', baseQuery: graphqlBaseQuery, endpoints: (builder) => ({ // 无参数查询示例,直接复用生成的SDK类型做泛型约束 getContinents: builder.query<Awaited<ReturnType<Sdk['continents']>>, void>({ query: () => ({ operation: 'continents' }) }), // 带参数查询示例 getContinent: builder.query<Awaited<ReturnType<Sdk['continent']>>, { code: string }>({ query: (variables) => ({ operation: 'continent', variables }) }) }) }) // 导出RTK自动生成的业务查询钩子,调用时自带完整类型提示 export const { useGetContinentsQuery, useGetContinentQuery } = api
上述实现直接复用了自动生成的SDK类型,不需要手动重复编写返回值和参数类型,全调用链路都有完整的类型校验。
内容的提问来源于stack exchange,提问作者Nenad
相关产品推荐
相关产品推荐

