From df77d8cd8bbee4d933797e00eb0cee452c25d1f9 Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 15 Apr 2026 16:47:54 +0900 Subject: [PATCH] test(svelte-query/createMutation): add type tests for generic type inference and callbacks (#10502) --- .../createMutation/createMutation.test-d.ts | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 packages/svelte-query/tests/createMutation/createMutation.test-d.ts diff --git a/packages/svelte-query/tests/createMutation/createMutation.test-d.ts b/packages/svelte-query/tests/createMutation/createMutation.test-d.ts new file mode 100644 index 00000000000..4ea6027949e --- /dev/null +++ b/packages/svelte-query/tests/createMutation/createMutation.test-d.ts @@ -0,0 +1,138 @@ +import { describe, expectTypeOf, it } from 'vitest' +import { QueryClient } from '@tanstack/query-core' +import { createMutation } from '../../src/index.js' +import type { DefaultError } from '@tanstack/query-core' +import type { CreateMutationResult } from '../../src/types.js' + +describe('createMutation', () => { + it('should infer TData from mutationFn return type', () => { + const mutation = createMutation(() => ({ + mutationFn: () => Promise.resolve('data'), + })) + + expectTypeOf(mutation.data).toEqualTypeOf() + expectTypeOf(mutation.error).toEqualTypeOf() + }) + + it('should infer TVariables from mutationFn parameter', () => { + const mutation = createMutation(() => ({ + mutationFn: (vars: { id: string }) => Promise.resolve(vars.id), + })) + + expectTypeOf(mutation.mutate).toBeCallableWith({ id: '1' }) + expectTypeOf(mutation.data).toEqualTypeOf() + }) + + it('should infer TOnMutateResult from onMutate return type', () => { + createMutation(() => ({ + mutationFn: () => Promise.resolve('data'), + onMutate: () => { + return { token: 'abc' } + }, + onSuccess: (_data, _variables, onMutateResult) => { + expectTypeOf(onMutateResult).toEqualTypeOf<{ token: string }>() + }, + onError: (_error, _variables, onMutateResult) => { + expectTypeOf(onMutateResult).toEqualTypeOf< + { token: string } | undefined + >() + }, + })) + }) + + it('should allow explicit generic types', () => { + const mutation = createMutation(() => ({ + mutationFn: (vars) => { + expectTypeOf(vars).toEqualTypeOf<{ id: number }>() + return Promise.resolve('result') + }, + })) + + expectTypeOf(mutation.data).toEqualTypeOf() + expectTypeOf(mutation.error).toEqualTypeOf() + }) + + it('should return correct CreateMutationResult type', () => { + const mutation = createMutation(() => ({ + mutationFn: () => Promise.resolve(42), + })) + + expectTypeOf(mutation).toEqualTypeOf< + CreateMutationResult + >() + }) + + it('should type mutateAsync with correct return type', () => { + const mutation = createMutation(() => ({ + mutationFn: (id: string) => Promise.resolve(id.length), + })) + + expectTypeOf(mutation.mutateAsync).toBeCallableWith('test') + expectTypeOf(mutation.mutateAsync('test')).toEqualTypeOf>() + }) + + it('should default TVariables to void when mutationFn has no parameters', () => { + const mutation = createMutation(() => ({ + mutationFn: () => Promise.resolve('data'), + })) + + expectTypeOf(mutation.mutate).toBeCallableWith() + }) + + it('should infer custom TError type', () => { + class CustomError extends Error { + code: number + constructor(code: number) { + super() + this.code = code + } + } + + const mutation = createMutation(() => ({ + mutationFn: () => Promise.resolve('data'), + })) + + expectTypeOf(mutation.error).toEqualTypeOf() + expectTypeOf(mutation.data).toEqualTypeOf() + }) + + it('should infer types for onSettled callback', () => { + createMutation(() => ({ + mutationFn: () => Promise.resolve(42), + onSettled: (data, error, _variables, _onMutateResult) => { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + }, + })) + }) + + it('should infer custom TError in onError callback', () => { + class CustomError extends Error { + code: number + constructor(code: number) { + super() + this.code = code + } + } + + createMutation(() => ({ + mutationFn: () => Promise.resolve('data'), + onError: (error) => { + expectTypeOf(error).toEqualTypeOf() + }, + })) + }) + + it('should accept queryClient as second argument', () => { + const queryClient = new QueryClient() + + const mutation = createMutation( + () => ({ + mutationFn: () => Promise.resolve('data'), + }), + () => queryClient, + ) + + expectTypeOf(mutation.data).toEqualTypeOf() + }) +})