fix(ts): Add typings for late variables in useMutation (#925)

This commit is contained in:
Piet de Vries 2020-04-02 20:28:03 +02:00 committed by GitHub
parent 0b99b3cfed
commit 576b49543a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 8 deletions

View File

@ -35,8 +35,13 @@ export interface UseMutationOptionsWithVariables<
variables: TVariables
}
export interface UseMutationReturn<TResult, TVariables> {
mutate: (variables?: TVariables, overrideOptions?: Pick<UseMutationOptions<any, OperationVariables>, 'update' | 'optimisticResponse' | 'context' | 'updateQueries' | 'refetchQueries' | 'awaitRefetchQueries' | 'errorPolicy' | 'fetchPolicy' | 'clientId'>) => Promise<FetchResult<any, Record<string, any>, Record<string, any>>>
type MutateOverrideOptions = Pick<UseMutationOptions<any, OperationVariables>, 'update' | 'optimisticResponse' | 'context' | 'updateQueries' | 'refetchQueries' | 'awaitRefetchQueries' | 'errorPolicy' | 'fetchPolicy' | 'clientId'>
type MutateResult = Promise<FetchResult<any, Record<string, any>, Record<string, any>>>
export type MutateWithOptionalVariables<TVariables> = (variables?: TVariables, overrideOptions?: MutateOverrideOptions) => MutateResult
export type MutateWithRequiredVariables<TVariables> = (variables: TVariables, overrideOptions?: MutateOverrideOptions) => MutateResult
export interface UseMutationReturn<TResult, TVariables, Mutate extends MutateWithOptionalVariables<TVariables> = MutateWithOptionalVariables<TVariables>> {
mutate: Mutate
loading: Ref<boolean>
error: Ref<Error>
called: Ref<boolean>
@ -71,6 +76,14 @@ export function useMutation<TResult = any, TVariables extends OperationVariables
options: UseMutationOptionsWithVariables<TResult, TVariables> | ReactiveFunction<UseMutationOptionsWithVariables<TResult, TVariables>>
): UseMutationReturn<TResult, TVariables>
/**
* Use a mutation that requires variables, but without a default.
*/
export function useMutation<TResult = any, TVariables extends OperationVariables = OperationVariables>(
document: DocumentNode | ReactiveFunction<DocumentNode>,
options?: UseMutationOptionsNoVariables<TResult, undefined> | ReactiveFunction<UseMutationOptionsNoVariables<TResult, undefined>>
): UseMutationReturn<TResult, TVariables, MutateWithRequiredVariables<TVariables>>
export function useMutation<
TResult,
TVariables extends OperationVariables

View File

@ -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<ExampleUpdateMutation, ExampleUpdateMutationVariables>(
const withVariablesInOptionsVariables = { id: "1", example: { name: "new" } };
const withVariablesInOptions = useMutation<ExampleUpdateMutation, ExampleUpdateMutationVariables>(
ExampleDocument,
{
awaitRefetchQueries: true,
@ -114,11 +115,81 @@ import { assertExactType } from "./assertions";
return {};
}
},
variables: withOptionsVariables
variables: withVariablesInOptionsVariables
}
);
withOptions.onDone(param => {
assertExactType<typeof withVariablesInOptions.mutate, MutateWithOptionalVariables<ExampleUpdateMutationVariables>>(
withVariablesInOptions.mutate
)
withVariablesInOptions.onDone(param => {
assertExactType<typeof param, FetchResult<ExampleUpdateMutation> | undefined>(param);
assertExactType<typeof param.data.exampleUpdate, ExampleUpdatePayload>(
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<ExampleUpdateMutation, ExampleUpdateMutationVariables>(
ExampleDocument
);
assertExactType<typeof withNoOptions.mutate, MutateWithRequiredVariables<ExampleUpdateMutationVariables>>(
withNoOptions.mutate
)
withNoOptions.onDone(param => {
assertExactType<typeof param, FetchResult<ExampleUpdateMutation> | undefined>(param);
assertExactType<typeof param.data.exampleUpdate, ExampleUpdatePayload>(
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<ExampleUpdateMutation, ExampleUpdateMutationVariables>(
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<ExampleUpdateMutation>) => {
mutationResult.data?.exampleUpdate;
},
updateQueries: {
query: (result, options) => {
options.mutationResult.data?.exampleUpdate;
return {};
}
}
}
);
assertExactType<typeof withNoVariablesInOptions.mutate, MutateWithRequiredVariables<ExampleUpdateMutationVariables>>(
withNoVariablesInOptions.mutate
)
withNoVariablesInOptions.onDone(param => {
assertExactType<typeof param, FetchResult<ExampleUpdateMutation> | undefined>(param);
assertExactType<typeof param.data.exampleUpdate, ExampleUpdatePayload>(
param.data.exampleUpdate