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

如何为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
        }
    );

关键原理说明

  1. 泛型约束:通过为ScopedMutator指定具体的Data类型(UpdateMyDetailsResponse),强制所有相关选项(如optimisticData、populateCache的参数)使用该类型,替代默认的any。
  2. 类型推断:当显式指定mutate<UpdateMyDetailsResponse>时,TypeScript会自动关联mutation返回值、缓存数据和选项参数的类型,确保所有环节的类型一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:32:08