ronantakizawa/codereview-bench huggingface dataset:
Repository: tanstack/query
File: packages/eslint-plugin-query/src/__tests__/exhaustive-deps.test.ts (TypeScript)

Code before:
          data: { deps: 'state.bar' },
        },
      ],
    },
    {
      name: 'should fail if queryFn is invalid while using FunctionExpression syntax',
      code: normalizeIndent`
        const id = 1;

        useQuery({
            queryKey: [],
            queryFn() {
              Promise.resolve(id)
            }
        })
      `,
      errors: [
        {
          suggestions: [
            {
              messageId: 'fixTo',
              output: normalizeIndent`
                const id = 1;

                useQuery({
                    queryKey: [, id],
                    queryFn() {
                      Promise.resolve(id)
                    }
                })
              `,
            },
          ],
          messageId: 'missingDeps',
          data: { deps: 'id' },
        },
      ],
    },
    {
      name: 'should fail if queryFn is a ternary expression with missing dep and a skipToken',
      code: normalizeIndent`
        import { useQuery, skipToken } from "@tanstack/react-query";
        const fetch = true

        function Component({ id }) {
          useQuery({
              queryKey: [],
              queryFn: fetch ? () => Promise.resolve(id) : skipToken
          })
        }
      `,

Review comment (suggestion):
I don't understand why the suggestions came with this missing first array index (eg. `[, `) 🤔 

Code after:
      name: 'should fail if queryFn is invalid while using FunctionExpression syntax',
      code: normalizeIndent`
        const id = 1;

        useQuery({
            queryKey: [],
            queryFn() {
              Promise.resolve(id)
            }
        })
      `,
      errors: [
        {
          suggestions: [
            {
              messageId: 'fixTo',
              output: normalizeIndent`
                const id = 1;

                useQuery({
                    queryKey: [id],
                    queryFn() {
                      Promise.resolve(id)
                    }
                })
              `,
            },
          ],
          messageId: 'missingDeps',
          data: { deps: 'id' },
        },
      ],
    },
    {
      name: 'should fail if queryFn is a ternary expression with missing dep and a skipToken',
      code: normalizeIndent`
        import { useQuery, skipToken } from "@tanstack/react-query";
        const fetch = true

        function Component({ id }) {
          useQuery({
              queryKey: [],
              queryFn: fetch ? () => Promise.resolve(id) : skipToken
          })
        }
      `,
      errors: [
        {
          suggestions: [
            {
              messageId: 'fixTo',
Repository: tanstack/query
File: packages/react-query/src/infiniteQueryOptions.ts (TypeScript)

Code before:
  TQueryKey,
  TPageParam
> & {
  initialData?: undefined
}

type NonUndefinedGuard<T> = T extends undefined ? never : T

export type DefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = unknown,
> = UseInfiniteQueryOptions<
  TQueryFnData,
  TError,
  TData,
  TQueryFnData,
  TQueryKey,
  TPageParam
> & {
  initialData:
    | NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>
    | (() => NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>)
    | undefined
}

export function infiniteQueryOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = unknown,
>(
  options: DefinedInitialDataInfiniteOptions<
    TQueryFnData,
    TError,
    TData,
    TQueryKey,
    TPageParam
  >,
): DefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError,
  TData,
  TQueryKey,
  TPageParam
> & {
  queryKey: DataTag<TQueryKey, InfiniteData<TQueryFnData>>
}

Review comment (suggestion):
pretty sure this should go to `UndefinedInitialDataInfiniteOptions`, like we have for `queryOptions`. compare:

https://github.com/TanStack/query/blob/fdb8ce1c38bc30fec9e984218b2fdc7802aef695/packages/react-query/src/queryOptions.ts#L15

Code after:
  TQueryFnData,
  TQueryKey,
  TPageParam
> & {
  initialData?:
    | undefined
    | InitialDataFunction<
        NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>
      >
}

type NonUndefinedGuard<T> = T extends undefined ? never : T

export type DefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = unknown,
> = UseInfiniteQueryOptions<
  TQueryFnData,
  TError,
  TData,
  TQueryFnData,
  TQueryKey,
  TPageParam
> & {
  initialData:
    | NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>
    | (() => NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>)
}

export function infiniteQueryOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = unknown,
>(
  options: DefinedInitialDataInfiniteOptions<
    TQueryFnData,
    TError,
    TData,
    TQueryKey,
    TPageParam
  >,
): DefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError,
  TData,
  TQueryKey,
Repository: tanstack/query
File: packages/query-core/src/utils.ts (TypeScript)

Code before:
  exact?: boolean
  /**
   * Include mutations matching this predicate function
   */
  predicate?: (mutation: Mutation<any, any, any>) => boolean
  /**
   * Include mutations matching this mutation key
   */
  mutationKey?: MutationKey
  /**
   * Filter by mutation status
   */
  status?: MutationStatus
}

export type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput)

export type QueryTypeFilter = 'all' | 'active' | 'inactive'

// UTILS

export const isServer = typeof window === 'undefined' || 'Deno' in globalThis

export function noop(): void {}

export const returnUndefined = noop as () => undefined

export function functionalUpdate<TInput, TOutput>(
  updater: Updater<TInput, TOutput>,
  input: TInput,
): TOutput {
  return typeof updater === 'function'
    ? (updater as (_: TInput) => TOutput)(input)
    : updater
}

export function isValidTimeout(value: unknown): value is number {
  return typeof value === 'number' && value >= 0 && value !== Infinity
}

export function timeUntilStale(updatedAt: number, staleTime?: number): number {
  return Math.max(updatedAt + (staleTime || 0) - Date.now(), 0)
}

export function resolveStaleTime<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
>(
  staleTime: undefined | StaleTime<TQueryFnData, TError, TData, TQueryKey>,

Review comment (suggestion):
would overloads also work?

```
export function noop(): undefined
export function noop(): void
export function noop() {}
```

Code after:
  exact?: boolean
  /**
   * Include mutations matching this predicate function
   */
  predicate?: (mutation: Mutation<any, any, any>) => boolean
  /**
   * Include mutations matching this mutation key
   */
  mutationKey?: MutationKey
  /**
   * Filter by mutation status
   */
  status?: MutationStatus
}

export type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput)

export type QueryTypeFilter = 'all' | 'active' | 'inactive'

// UTILS

export const isServer = typeof window === 'undefined' || 'Deno' in globalThis

export function noop(): void
export function noop(): undefined
export function noop() {}

export function functionalUpdate<TInput, TOutput>(
  updater: Updater<TInput, TOutput>,
  input: TInput,
): TOutput {
  return typeof updater === 'function'
    ? (updater as (_: TInput) => TOutput)(input)
    : updater
}

export function isValidTimeout(value: unknown): value is number {
  return typeof value === 'number' && value >= 0 && value !== Infinity
}

export function timeUntilStale(updatedAt: number, staleTime?: number): number {
  return Math.max(updatedAt + (staleTime || 0) - Date.now(), 0)
}

export function resolveStaleTime<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
>(
  staleTime: undefined | StaleTime<TQueryFnData, TError, TData, TQueryKey>,
Repository: tanstack/query
File: packages/query-core/src/types.ts (TypeScript)

Code before:

export type Override<TTargetA, TTargetB> = {
  [AKey in keyof TTargetA]: AKey extends keyof TTargetB
    ? TTargetB[AKey]
    : TTargetA[AKey]
}

export type NoInfer<T> = [T][T extends any ? 0 : never]

export interface Register {
  // defaultError: Error
  // queryMeta: Record<string, unknown>
  // mutationMeta: Record<string, unknown>
}

export type DefaultError = Register extends {
  defaultError: infer TError
}
  ? TError
  : Error

export type QueryKey = ReadonlyArray<unknown>

export declare const dataTagSymbol: unique symbol
export declare const dataTagErrorSymbol: unique symbol
export type DataTag<TType, TValue, TError = unknown> = TType & {
  [dataTagSymbol]: TValue
  [dataTagErrorSymbol]: TError
}

export type QueryFunction<
  T = unknown,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = never,
> = (context: QueryFunctionContext<TQueryKey, TPageParam>) => T | Promise<T>

export type StaleTime<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
> = number | ((query: Query<TQueryFnData, TError, TData, TQueryKey>) => number)

export type Enabled<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
> =
  | boolean
  | ((query: Query<TQueryFnData, TError, TData, TQueryKey>) => boolean)

Review comment (suggestion):
```suggestion
export type DataTag<TType, TValue, TError = DefaultError> = TType & {
```

Code after:

export type Override<TTargetA, TTargetB> = {
  [AKey in keyof TTargetA]: AKey extends keyof TTargetB
    ? TTargetB[AKey]
    : TTargetA[AKey]
}

export type NoInfer<T> = [T][T extends any ? 0 : never]

export interface Register {
  // defaultError: Error
  // queryMeta: Record<string, unknown>
  // mutationMeta: Record<string, unknown>
}

export type DefaultError = Register extends {
  defaultError: infer TError
}
  ? TError
  : Error

export type QueryKey = ReadonlyArray<unknown>

export declare const dataTagSymbol: unique symbol
export declare const dataTagErrorSymbol: unique symbol
export declare const unsetMarker: unique symbol
export type UnsetMarker = typeof unsetMarker
export type DataTag<TType, TValue, TError = UnsetMarker> = TType & {
  [dataTagSymbol]: TValue
  [dataTagErrorSymbol]: TError
}

export type QueryFunction<
  T = unknown,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = never,
> = (context: QueryFunctionContext<TQueryKey, TPageParam>) => T | Promise<T>

export type StaleTime<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
> = number | ((query: Query<TQueryFnData, TError, TData, TQueryKey>) => number)

export type Enabled<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
> =
Repository: tanstack/query
File: examples/angular/auto-refetching/src/app/app.config.ts (TypeScript)

Code before:
  withFetch,
} from '@angular/common/http'
import {
  QueryClient,
  provideTanStackQuery,
  withDevtools,
} from '@tanstack/angular-query-experimental'
import { importProvidersFrom } from '@angular/core'
import { MockApiInterceptor } from './interceptor/mock-api.interceptor'
import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch()),
    provideTanStackQuery(
      new QueryClient({
        defaultOptions: {
          queries: {
            gcTime: 1000 * 60 * 60 * 24, // 24 hours
          },
        },
      }),
      withDevtools(),
    ),
    // Registers the MockApiInterceptor for simulating API calls
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MockApiInterceptor,
      multi: true,
    },
    importProvidersFrom(HttpClientModule),
  ],
}


Review comment (suggestion):
Can you use a functional interceptor and `withInterceptors` instead? See the [rxjs example](https://github.com/TanStack/query/blob/b7bad3dfda38404bbdebd82f921dea94b9744220/examples/angular/rxjs/src/app/app.config.ts#L18)

Code after:
import {
  provideHttpClient,
  withFetch,
  withInterceptors,
} from '@angular/common/http'
import {
  QueryClient,
  provideTanStackQuery,
  withDevtools,
} from '@tanstack/angular-query-experimental'
import { mockInterceptor } from './interceptor/mock-api.interceptor'
import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch(), withInterceptors([mockInterceptor])),
    provideTanStackQuery(
      new QueryClient({
        defaultOptions: {
          queries: {
            gcTime: 1000 * 60 * 60 * 24, // 24 hours
          },
        },
      }),
      withDevtools(),
    ),
  ],
}
Repository: tanstack/query
File: examples/angular/auto-refetching/src/app/app.config.ts (TypeScript)

Code before:
  withDevtools,
} from '@tanstack/angular-query-experimental'
import { importProvidersFrom } from '@angular/core'
import { MockApiInterceptor } from './interceptor/mock-api.interceptor'
import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch()),
    provideTanStackQuery(
      new QueryClient({
        defaultOptions: {
          queries: {
            gcTime: 1000 * 60 * 60 * 24, // 24 hours
          },
        },
      }),
      withDevtools(),
    ),
    // Registers the MockApiInterceptor for simulating API calls
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MockApiInterceptor,
      multi: true,
    },
    importProvidersFrom(HttpClientModule),
  ],
}


Review comment (suggestion):
Not needed when using `provideHttpClient `

```suggestion
```

Code after:
import {
  provideHttpClient,
  withFetch,
  withInterceptors,
} from '@angular/common/http'
import {
  QueryClient,
  provideTanStackQuery,
  withDevtools,
} from '@tanstack/angular-query-experimental'
import { mockInterceptor } from './interceptor/mock-api.interceptor'
import type { ApplicationConfig } from '@angular/core'

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch(), withInterceptors([mockInterceptor])),
    provideTanStackQuery(
      new QueryClient({
        defaultOptions: {
          queries: {
            gcTime: 1000 * 60 * 60 * 24, // 24 hours
          },
        },
      }),
      withDevtools(),
    ),
  ],
}
Repository: tanstack/query
File: packages/angular-query-experimental/src/infinite-query-options.ts (TypeScript)

Code before:
import type {
  DataTag,
  DefaultError,
  InfiniteData,
  QueryKey,
} from '@tanstack/query-core'
import type { CreateInfiniteQueryOptions, NonUndefinedGuard } from './types'

/**
 * @public
 */
export type UndefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = Array<any>,
  TPageParam = unknown,
> = CreateInfiniteQueryOptions<
  TQueryFnData,
  TError,
  TData,
  TQueryFnData,
  TQueryKey,
  TPageParam
> & {
  initialData?: undefined
}

/**
 * @public
 */
export type DefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = Array<any>,
  TPageParam = unknown,
> = CreateInfiniteQueryOptions<
  TQueryFnData,
  TError,
  TData,

Review comment (suggestion):
my idea was to keep this to:

```
TQueryKey extends QueryKey = QueryKey,
```

and then just change what `QueryKey` is:

```diff
- export type QueryKey = ReadonlyArray<unknown>
+ export type QueryKey = Array<any>
```


Code after:
import type {
  DataTag,
  DefaultError,
  InfiniteData,
  QueryKey,
} from '@tanstack/query-core'
import type { CreateInfiniteQueryOptions, NonUndefinedGuard } from './types'

/**
 * @public
 */
export type UndefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = unknown,
> = CreateInfiniteQueryOptions<
  TQueryFnData,
  TError,
  TData,
  TQueryFnData,
  TQueryKey,
  TPageParam
> & {
  initialData?: undefined
}

/**
 * @public
 */
export type DefinedInitialDataInfiniteOptions<
  TQueryFnData,
  TError = DefaultError,
  TData = InfiniteData<TQueryFnData>,
  TQueryKey extends QueryKey = QueryKey,
  TPageParam = unknown,
> = CreateInfiniteQueryOptions<
  TQueryFnData,
  TError,
  TData,
Repository: tanstack/query
File: packages/react-query/src/__tests__/useQueries.test.tsx (TypeScript)

Code before:
              client.setQueryData([key1], 'first result updated')
            }}
          >
            update
          </button>
        </div>
      )
    }

    const rendered = render(<Page />)

    await waitFor(() => rendered.getByText('data: pending'))
    await waitFor(() =>
      rendered.getByText('data: first result, second result, third result'),
    )

    fireEvent.click(rendered.getByRole('button', { name: /update/i }))

    await waitFor(() =>
      rendered.getByText(
        'data: first result updated, second result, third result',
      ),
    )
  })

  it('should return correct data for dynamic queries with mixed result types', async () => {
    const key1 = queryKey()
    const key2 = queryKey()

    function Page() {
      const Queries1 = {
        get: () =>
          queryOptions({
            queryKey: key1,
            queryFn: async () => {
              await sleep(10)
              return 1
            },
          }),
      }
      const Queries2 = {
        get: () =>
          queryOptions({
            queryKey: key2,
            queryFn: async () => {
              await sleep(10)
              return true
            },
          }),
      }


Review comment (suggestion):
type only tests should please go towards the dedicated `.test-d.tsx` files:

- `packages/react-query/src/__tests__/useQueries.test-d.tsx`
- `packages/react-query/src/__tests__/useSuspenseQueries.test-d.tsx`

Code after:
              client.setQueryData([key1], 'first result updated')
            }}
          >
            update
          </button>
        </div>
      )
    }

    const rendered = render(<Page />)

    await waitFor(() => rendered.getByText('data: pending'))
    await waitFor(() =>
      rendered.getByText('data: first result, second result, third result'),
    )

    fireEvent.click(rendered.getByRole('button', { name: /update/i }))

    await waitFor(() =>
      rendered.getByText(
        'data: first result updated, second result, third result',
      ),
    )
  })
})
Repository: tanstack/query
File: packages/solid-query/src/__tests__/createQueries.test-d.tsx (TypeScript)

Code before:
        }),
    }
    const Queries2 = {
      get: () =>
        queryOptions({
          queryKey: ['key2'],
          queryFn: () => Promise.resolve(true),
        }),
    }

    const queries1List = [1, 2, 3].map(() => ({ ...Queries1.get() }))
    const result = createQueries(() => ({
      queries: [...queries1List, { ...Queries2.get() }],
    }))

    expectTypeOf(result).toEqualTypeOf<
      [
        ...Array<CreateQueryResult<number, Error>>,
        CreateQueryResult<boolean, Error>,
      ]
    >()

    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    if (!result[0]) {
      throw new Error('Type check failure')
    }
    expectTypeOf(result[0].data).toEqualTypeOf<number | boolean | undefined>()
  })
})


Review comment (suggestion):
that’s not how type-tests work. They don’t have a runtime - the `it` function never gets executed by vitest.

it should be fine to just remove that.

Code after:
import { describe, expectTypeOf, it } from 'vitest'
import { createQueries, queryOptions } from '..'
import type { CreateQueryResult } from '..'

describe('createQueries', () => {
  it('should return correct data for dynamic queries with mixed result types', () => {
    const Queries1 = {
      get: () =>
        queryOptions({
          queryKey: ['key1'],
          queryFn: () => Promise.resolve(1),
        }),
    }
    const Queries2 = {
      get: () =>
        queryOptions({
          queryKey: ['key2'],
          queryFn: () => Promise.resolve(true),
        }),
    }

    const queries1List = [1, 2, 3].map(() => ({ ...Queries1.get() }))
    const result = createQueries(() => ({
      queries: [...queries1List, { ...Queries2.get() }],
    }))

    expectTypeOf(result).toEqualTypeOf<
      [
        ...Array<CreateQueryResult<number, Error>>,
        CreateQueryResult<boolean, Error>,
      ]
    >()
  })
})
Repository: tanstack/query
File: packages/react-query/src/__tests__/useSuspenseQueries.test-d.tsx (TypeScript)

Code before:
      }

      const queryResults = useCustomQueries()
      const data = queryResults[0].data

      expectTypeOf(data).toEqualTypeOf<Data>()
    })
  })

  it('queryOptions with initialData works on useSuspenseQueries', () => {
    const query1 = queryOptions({
      queryKey: ['key1'],
      queryFn: () => 'Query Data',
      initialData: 'initial data',
    })

    const queryResults = useSuspenseQueries({ queries: [query1] })
    const query1Data = queryResults[0].data

    expectTypeOf(query1Data).toEqualTypeOf<string>()
  })

  it('queryOptions with initialData and skipToken in queryFn should not work on useSuspenseQueries', () => {
    const query1 = queryOptions({
      queryKey: ['key1'],
      queryFn: skipToken,
      initialData: 'initial data',
    })

    // @ts-expect-error
    useSuspenseQueries({ queries: [query1] })
  })
})


Review comment (suggestion):
would be good to have a test that has a conditional skipToken:

```
queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5)
```

because that’s a lot closer to a real world use-case

Code after:
      }

      const queryResults = useCustomQueries()
      const data = queryResults[0].data

      expectTypeOf(data).toEqualTypeOf<Data>()
    })
  })

  it('queryOptions with initialData works on useSuspenseQueries', () => {
    const query1 = queryOptions({
      queryKey: ['key1'],
      queryFn: () => 'Query Data',
      initialData: 'initial data',
    })

    const queryResults = useSuspenseQueries({ queries: [query1] })
    const query1Data = queryResults[0].data

    expectTypeOf(query1Data).toEqualTypeOf<string>()
  })

  it('queryOptions with skipToken in queryFn should not work on useSuspenseQueries', () => {
    const query1 = queryOptions({
      queryKey: ['key1'],
      queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
    })

    const query2 = queryOptions({
      queryKey: ['key1'],
      queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5),
      initialData: 5,
    })

    // @ts-expect-error
    useSuspenseQueries({ queries: [query1] })
    // @ts-expect-error
    useSuspenseQueries({ queries: [query2] })
  })
})