如何为Vercel SWR乐观更新实现完整TypeScript类型校验?
为SWR Mutation实现完整类型校验的方案
要解决乐观数据(optimisticData)和缓存更新函数(populateCache)的类型缺失问题,核心是为SWR的mutate函数指定明确的泛型类型,替代默认的any。以下是两种可行的实现方式:
方法一:直接为Mutate调用指定类型
通过显式声明泛型类型和选项类型,让TypeScript完成类型校验:
import type { MutatorOptions } from 'swr'; type MyDetails = { firstName: string lastName: string } type UpdateMyDetailsResponse = { updateMyDetails: MyDetails } const mutateMyDetails = (details: MyDetails) => { // 定义类型明确的mutation选项 const opts: MutatorOptions<UpdateMyDetailsResponse> = { optimisticData: { updateMyDetails: { ...details } }, // 现在会校验是否匹配UpdateMyDetailsResponse结构 rollbackOnError: true, populateCache: (result, currentData) => { // result自动推断为UpdateMyDetailsResponse // currentData自动推断为UpdateMyDetailsResponse | undefined return result; }, revalidate: false }; // 调用mutate时显式指定返回值类型 return mutate<UpdateMyDetailsResponse>( 'my-details', () => client.request<UpdateMyDetailsResponse>( gql` mutation UpdateMyDetails($details: MyDetails!) { updateMyDetails(details: $details) { firstName lastName } } `, { details }, ), opts ); };
方法二:创建通用的Typed Mutate函数
如果需要多次复用同类型的mutate操作,可以封装一个类型化的mutate工具函数:
import type { ScopedMutator } from 'swr'; // 生成指定数据类型的typed mutate函数 const getTypedMutator = <Data>() => mutate as ScopedMutator<Data>; type MyDetails = { firstName: string lastName: string } type UpdateMyDetailsResponse = { updateMyDetails: MyDetails } // 为当前数据类型创建专属mutate const myDetailsMutator = getTypedMutator<UpdateMyDetailsResponse>(); const mutateMyDetails = (details: MyDetails) => myDetailsMutator( 'my-details', () => client.request<UpdateMyDetailsResponse>( gql` mutation UpdateMyDetails($details: MyDetails!) { updateMyDetails(details: $details) { firstName lastName } } `, { details }, ), { optimisticData: { updateMyDetails: { ...details } }, // 自动校验类型 rollbackOnError: true, populateCache: (result, currentData) => result, // 参数自动类型推断 revalidate: false } );
关键原理说明
- 泛型约束:通过为
ScopedMutator指定具体的Data类型(UpdateMyDetailsResponse),强制所有相关选项(如optimisticData、populateCache的参数)使用该类型,替代默认的any。 - 类型推断:当显式指定
mutate<UpdateMyDetailsResponse>时,TypeScript会自动关联mutation返回值、缓存数据和选项参数的类型,确保所有环节的类型一致性。
内容的提问来源于stack exchange,提问作者caprica
相关产品推荐
相关产品推荐

