Mutation Types

Purpose

This subtopic defines the TypeScript types that form the foundation for remote mutation handling within the mutation feature. It addresses the need for strongly-typed mutation fetchers, configuration options, triggers, and mutation responses to enable safe, predictable, and flexible mutation operations. These types provide a clear contract for how mutation hooks are used, what options are supported, and how mutation results and states are exposed to consumers.

By encapsulating mutation-related types separately, the system ensures type safety and extensibility, enabling advanced features such as optimistic updates, conditional cache population, rollback policies, and precise triggering semantics without ambiguity or runtime errors.

Functionality

The core functionality of this subtopic revolves around describing:

These types allow the mutation hook implementation to support:

Key Type Relationships

Code Snippet Example

export type MutationFetcher<
  Data = unknown,
  SWRKey extends Key = Key,
  ExtraArg = unknown
> = SWRKey extends () => infer Arg | null | undefined | false
  ? (key: Arg, options: FetcherOptions<ExtraArg>) => FetcherResponse<Data>
  : SWRKey extends null | undefined | false
  ? never
  : SWRKey extends infer Arg
  ? (key: Arg, options: FetcherOptions<ExtraArg>) => FetcherResponse<Data>
  : never

This snippet illustrates how the fetcher type adapts its key argument based on the form of the mutation key.

Integration

These types integrate closely with the parent topic, Remote Data Mutation, and its other subtopics:

Furthermore, these types are foundational for middleware and utility functions that extend or customize mutation behaviors, such as optimistic UI updates or error rollback strategies. They facilitate strong typing across the mutation ecosystem, reducing bugs and improving developer experience.

Diagram

classDiagram
    class MutationFetcher {
      <<type>>
      + (key: Arg, options: FetcherOptions) => Data | Promise<Data>
    }

    class SWRMutationConfiguration {
      + revalidate: boolean | function
      + populateCache: boolean | function
      + optimisticData: any | function
      + rollbackOnError: boolean | function
      + fetcher: MutationFetcher
      + onSuccess(data, key, config): void
      + onError(error, key, config): void
    }

    class TriggerFunction {
      <<interface>>
      + (extraArgument?, options?): Promise<Data | undefined>
    }

    class SWRMutationResponse {
      + data
      + error
      + isMutating: boolean
      + trigger: TriggerFunction
      + reset(): void
    }

    class SWRMutationHook {
      <<function>>
      + (key, fetcher, options?): SWRMutationResponse
    }

    MutationFetcher <|-- SWRMutationConfiguration : uses
    SWRMutationConfiguration <-- TriggerFunction : uses
    TriggerFunction <-- SWRMutationResponse : exposes
    SWRMutationResponse <-- SWRMutationHook : returns

This class diagram visualizes the core types and their relationships, emphasizing how fetchers, configurations, triggers, responses, and hooks are connected to support the mutation mechanism.