diff --git a/packages/vue-apollo-composable/src/useMutation.ts b/packages/vue-apollo-composable/src/useMutation.ts index e82033c..d8c3086 100644 --- a/packages/vue-apollo-composable/src/useMutation.ts +++ b/packages/vue-apollo-composable/src/useMutation.ts @@ -35,8 +35,13 @@ export interface UseMutationOptionsWithVariables< variables: TVariables } -export interface UseMutationReturn { - mutate: (variables?: TVariables, overrideOptions?: Pick, 'update' | 'optimisticResponse' | 'context' | 'updateQueries' | 'refetchQueries' | 'awaitRefetchQueries' | 'errorPolicy' | 'fetchPolicy' | 'clientId'>) => Promise, Record>> +type MutateOverrideOptions = Pick, 'update' | 'optimisticResponse' | 'context' | 'updateQueries' | 'refetchQueries' | 'awaitRefetchQueries' | 'errorPolicy' | 'fetchPolicy' | 'clientId'> +type MutateResult = Promise, Record>> +export type MutateWithOptionalVariables = (variables?: TVariables, overrideOptions?: MutateOverrideOptions) => MutateResult +export type MutateWithRequiredVariables = (variables: TVariables, overrideOptions?: MutateOverrideOptions) => MutateResult + +export interface UseMutationReturn = MutateWithOptionalVariables> { + mutate: Mutate loading: Ref error: Ref called: Ref @@ -71,6 +76,14 @@ export function useMutation | ReactiveFunction> ): UseMutationReturn +/** + * Use a mutation that requires variables, but without a default. + */ +export function useMutation( + document: DocumentNode | ReactiveFunction, + options?: UseMutationOptionsNoVariables | ReactiveFunction> +): UseMutationReturn> + export function useMutation< TResult, TVariables extends OperationVariables diff --git a/packages/vue-apollo-composable/tests/types/useMutation-types.test.ts b/packages/vue-apollo-composable/tests/types/useMutation-types.test.ts index e014736..9981d14 100644 --- a/packages/vue-apollo-composable/tests/types/useMutation-types.test.ts +++ b/packages/vue-apollo-composable/tests/types/useMutation-types.test.ts @@ -1,5 +1,5 @@ import { FetchResult } from "apollo-link"; -import { useMutation } from "../../src"; +import { useMutation, MutateWithOptionalVariables, MutateWithRequiredVariables } from "../../src"; import { ExampleDocument, ExampleUpdateMutation, @@ -87,13 +87,14 @@ import { assertExactType } from "./assertions"; } // ============================================================================= -// With all things typed and with options +// With all things typed and with options and variables // - TResult should be the mutation type // - TVariables should be the variables type +// - mutate should have an optional variables parameter // ============================================================================= { - const withOptionsVariables = { id: "1", example: { name: "new" } }; - const withOptions = useMutation( + const withVariablesInOptionsVariables = { id: "1", example: { name: "new" } }; + const withVariablesInOptions = useMutation( ExampleDocument, { awaitRefetchQueries: true, @@ -114,11 +115,81 @@ import { assertExactType } from "./assertions"; return {}; } }, - variables: withOptionsVariables + variables: withVariablesInOptionsVariables } ); - withOptions.onDone(param => { + assertExactType>( + withVariablesInOptions.mutate + ) + + withVariablesInOptions.onDone(param => { + assertExactType | undefined>(param); + assertExactType( + param.data.exampleUpdate + ); + }); +} + +// ============================================================================= +// With all things typed and without options +// - TResult should be the mutation type +// - TVariables should be the variables type +// - mutate should have a required variables parameter +// ============================================================================= +{ + const withNoOptions = useMutation( + ExampleDocument + ); + + assertExactType>( + withNoOptions.mutate + ) + + withNoOptions.onDone(param => { + assertExactType | undefined>(param); + assertExactType( + param.data.exampleUpdate + ); + }); +} + +// ============================================================================= +// With all things typed and with options, but without variables +// - TResult should be the mutation type +// - TVariables should be the variables type +// - mutate should have a required variables parameter +// ============================================================================= +{ + const withNoVariablesInOptions = useMutation( + ExampleDocument, + { + awaitRefetchQueries: true, + clientId: "37Hn7m", + context: "any", + errorPolicy: "all", + fetchPolicy: "cache-first", + optimisticResponse: (vars: ExampleUpdateMutationVariables) => ({ + exampleUpdate: { example: { id: "" } } + }), + refetchQueries: ["firstQuery", "secondQuery"], + update: (proxy, mutationResult: FetchResult) => { + mutationResult.data?.exampleUpdate; + }, + updateQueries: { + query: (result, options) => { + options.mutationResult.data?.exampleUpdate; + return {}; + } + } + } + ); + + assertExactType>( + withNoVariablesInOptions.mutate + ) + + withNoVariablesInOptions.onDone(param => { assertExactType | undefined>(param); assertExactType( param.data.exampleUpdate