Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(react-query): improved TypeScript engine halt due to return type inference in useSuspenseQueries #911

Merged
merged 4 commits into from
Jun 13, 2024

Conversation

gwansikk
Copy link
Collaborator

@gwansikk gwansikk commented Jun 12, 2024

Overview

fixed: #889
Fixes a bug where the TypeScript engine would hang due to the complex return type of useSuspenseQueries.

Issue

// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;

declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
// return type 🤔
}): T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };

When you check the built type declarations, you'll see that the return type of useSuspenseQueries is determined through very complex type inference. This complexity in the inference process can cause the TypeScript engine to hang. (This issue is also documented in the TypeScript GitHub issues.)

// return type 🤔
T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];

Currently, the return type is inferred for complex types.

Improvement

// useSuspenseQueries.ts
export function useSuspenseQueries<T extends any[]>({
  queries,
  context,
}: {
  queries: readonly [...SuspenseQueriesOptions<T>]
  context?: UseQueryOptions['context']
}): SuspenseQueriesResults<T> {
  return useQueries({
    queries: queries.map((query: typeof queries) => ({ ...query, suspense: true })),
    context,
  }) as SuspenseQueriesResults<T>
}

Specify the return type explicitly to prevent TypeScript’s inference from hanging.

// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;
declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
}): SuspenseQueriesResults<T>;

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };

The complex inference process is replaced with SuspenseQueriesResults, simplifying it and preventing the TypeScript engine from hanging.

PR Checklist

  • I did below actions if need
  1. I read the Contributing Guide
  2. I added documents and tests.

@gwansikk gwansikk changed the title improved TypeScript engine halt due to return type inference in useSuspenseQueries fix(react-query): improved TypeScript engine halt due to return type inference in useSuspenseQueries Jun 12, 2024
@manudeli manudeli self-assigned this Jun 12, 2024
@manudeli manudeli requested review from manudeli and removed request for minsoo-web and okinawaa June 12, 2024 14:08
@codecov-commenter
Copy link

codecov-commenter commented Jun 12, 2024

Codecov Report

Attention: Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.

Project coverage is 83.44%. Comparing base (40e4132) to head (b6c3a7f).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #911   +/-   ##
=======================================
  Coverage   83.44%   83.44%           
=======================================
  Files          33       33           
  Lines         435      435           
  Branches      100      100           
=======================================
  Hits          363      363           
  Misses         62       62           
  Partials       10       10           
Components Coverage Δ
@suspensive/react 96.98% <ø> (ø)
@suspensive/react-query 13.79% <0.00%> (ø)
@suspensive/react-await 100.00% <ø> (ø)
@suspensive/react-image 23.52% <ø> (ø)

Copy link

changeset-bot bot commented Jun 13, 2024

🦋 Changeset detected

Latest commit: b6c3a7f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@suspensive/react-query Patch
@suspensive/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Member

@manudeli manudeli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much..!👍👍👍👍👍 I've had a lot of trouble with this problem, so I'll check to see if there are any TypeScript engine issues even after release new version of @suspensive/react-query!

@manudeli manudeli merged commit c6c0640 into toss:main Jun 13, 2024
8 checks passed
@github-actions github-actions bot mentioned this pull request Jun 13, 2024
manudeli pushed a commit that referenced this pull request Jun 13, 2024
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @suspensive/react@2.0.5

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-await@0.0.19

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-image@0.0.13

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-query@2.0.5

### Patch Changes

- [#911](#911)
[`c6c0640`](c6c0640)
Thanks [@gwansikk](https://github.com/gwansikk)! - fix(react-query):
improved TypeScript engine halt due to return type inference in
useSuspenseQueries

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

- Updated dependencies
\[[`0c86892`](0c86892)]:
    -   @suspensive/react@2.0.5

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
manudeli added a commit that referenced this pull request Aug 3, 2024
…inference in useSuspenseQueries (#911)

# Overview

fixed: #889
Fixes a bug where the TypeScript engine would hang due to the complex
return type of useSuspenseQueries.

## Issue

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;

declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
// return type 🤔
}): T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

When you check the built type declarations, you'll see that the return
type of useSuspenseQueries is determined through very complex type
inference. This complexity in the inference process can cause the
TypeScript engine to hang. (This issue is also documented in the
TypeScript GitHub issues.)

- microsoft/TypeScript#38182

```ts
// return type 🤔
T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];
```

Currently, the return type is inferred for complex types.

## Improvement

```ts
// useSuspenseQueries.ts
export function useSuspenseQueries<T extends any[]>({
  queries,
  context,
}: {
  queries: readonly [...SuspenseQueriesOptions<T>]
  context?: UseQueryOptions['context']
}): SuspenseQueriesResults<T> {
  return useQueries({
    queries: queries.map((query: typeof queries) => ({ ...query, suspense: true })),
    context,
  }) as SuspenseQueriesResults<T>
}
```

Specify the return type explicitly to prevent TypeScript’s inference
from hanging.

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;
declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
}): SuspenseQueriesResults<T>;

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

The complex inference process is replaced with `SuspenseQueriesResults`,
simplifying it and preventing the TypeScript engine from hanging.

## PR Checklist

- [x] I did below actions if need

1. I read the [Contributing
Guide](https://github.com/suspensive/react/blob/main/CONTRIBUTING.md)
2. I added documents and tests.

---------

Co-authored-by: Jonghyeon Ko <jonghyeon@toss.im>
manudeli added a commit that referenced this pull request Aug 3, 2024
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @suspensive/react@2.0.5

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-await@0.0.19

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-image@0.0.13

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-query@2.0.5

### Patch Changes

- [#911](#911)
[`c6c0640`](c6c0640)
Thanks [@gwansikk](https://github.com/gwansikk)! - fix(react-query):
improved TypeScript engine halt due to return type inference in
useSuspenseQueries

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

- Updated dependencies
\[[`0c86892`](0c86892)]:
    -   @suspensive/react@2.0.5

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
manudeli pushed a commit that referenced this pull request Aug 3, 2024
…inference in useSuspenseQueries (#911)

# Overview

fixed: #889
Fixes a bug where the TypeScript engine would hang due to the complex
return type of useSuspenseQueries.

## Issue

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;

declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
// return type 🤔
}): T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

When you check the built type declarations, you'll see that the return
type of useSuspenseQueries is determined through very complex type
inference. This complexity in the inference process can cause the
TypeScript engine to hang. (This issue is also documented in the
TypeScript GitHub issues.)

- microsoft/TypeScript#38182

```ts
// return type 🤔
T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];
```

Currently, the return type is inferred for complex types.

## Improvement

```ts
// useSuspenseQueries.ts
export function useSuspenseQueries<T extends any[]>({
  queries,
  context,
}: {
  queries: readonly [...SuspenseQueriesOptions<T>]
  context?: UseQueryOptions['context']
}): SuspenseQueriesResults<T> {
  return useQueries({
    queries: queries.map((query: typeof queries) => ({ ...query, suspense: true })),
    context,
  }) as SuspenseQueriesResults<T>
}
```

Specify the return type explicitly to prevent TypeScript’s inference
from hanging.

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;
declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
}): SuspenseQueriesResults<T>;

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

The complex inference process is replaced with `SuspenseQueriesResults`,
simplifying it and preventing the TypeScript engine from hanging.

## PR Checklist

- [x] I did below actions if need

1. I read the [Contributing
Guide](https://github.com/suspensive/react/blob/main/CONTRIBUTING.md)
2. I added documents and tests.

---------
manudeli added a commit that referenced this pull request Aug 3, 2024
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @suspensive/react@2.0.5

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-await@0.0.19

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-image@0.0.13

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-query@2.0.5

### Patch Changes

- [#911](#911)
[`c6c0640`](c6c0640)
Thanks [@gwansikk](https://github.com/gwansikk)! - fix(react-query):
improved TypeScript engine halt due to return type inference in
useSuspenseQueries

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

- Updated dependencies
\[[`0c86892`](0c86892)]:
    -   @suspensive/react@2.0.5
manudeli added a commit that referenced this pull request Aug 3, 2024
…inference in useSuspenseQueries (#911)

# Overview

fixed: #889
Fixes a bug where the TypeScript engine would hang due to the complex
return type of useSuspenseQueries.

## Issue

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;

declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
// return type 🤔
}): T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

When you check the built type declarations, you'll see that the return
type of useSuspenseQueries is determined through very complex type
inference. This complexity in the inference process can cause the
TypeScript engine to hang. (This issue is also documented in the
TypeScript GitHub issues.)

- microsoft/TypeScript#38182

```ts
// return type 🤔
T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];
```

Currently, the return type is inferred for complex types.

## Improvement

```ts
// useSuspenseQueries.ts
export function useSuspenseQueries<T extends any[]>({
  queries,
  context,
}: {
  queries: readonly [...SuspenseQueriesOptions<T>]
  context?: UseQueryOptions['context']
}): SuspenseQueriesResults<T> {
  return useQueries({
    queries: queries.map((query: typeof queries) => ({ ...query, suspense: true })),
    context,
  }) as SuspenseQueriesResults<T>
}
```

Specify the return type explicitly to prevent TypeScript’s inference
from hanging.

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;
declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
}): SuspenseQueriesResults<T>;

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

The complex inference process is replaced with `SuspenseQueriesResults`,
simplifying it and preventing the TypeScript engine from hanging.

## PR Checklist

- [x] I did below actions if need

1. I read the [Contributing
Guide](https://github.com/suspensive/react/blob/main/CONTRIBUTING.md)
2. I added documents and tests.

---------

Co-authored-by: Jonghyeon Ko <jonghyeon@toss.im>
manudeli added a commit that referenced this pull request Aug 3, 2024
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @suspensive/react@2.0.5

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-await@0.0.19

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-image@0.0.13

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-query@2.0.5

### Patch Changes

- [#911](#911)
[`c6c0640`](c6c0640)
Thanks [@gwansikk](https://github.com/gwansikk)! - fix(react-query):
improved TypeScript engine halt due to return type inference in
useSuspenseQueries

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

- Updated dependencies
\[[`0c86892`](0c86892)]:
    -   @suspensive/react@2.0.5
manudeli added a commit that referenced this pull request Aug 3, 2024
…inference in useSuspenseQueries (#911)

# Overview

fixed: #889
Fixes a bug where the TypeScript engine would hang due to the complex
return type of useSuspenseQueries.

## Issue

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;

declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
// return type 🤔
}): T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

When you check the built type declarations, you'll see that the return
type of useSuspenseQueries is determined through very complex type
inference. This complexity in the inference process can cause the
TypeScript engine to hang. (This issue is also documented in the
TypeScript GitHub issues.)

- microsoft/TypeScript#38182

```ts
// return type 🤔
T extends [] ? [] : T extends [infer Head] ? [GetSuspenseResults<Head>] : T extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_1 ? T_1 extends […Tail] ? T_1 extends [] ? [] : T_1 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_1 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_2 ? T_2 extends […Tail] ? T_2 extends [] ? [] : T_2 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_2 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_3 ? T_3 extends […Tail] ? T_3 extends [] ? [] : T_3 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_3 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_4 ? T_4 extends […Tail] ? T_4 extends [] ? [] : T_4 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_4 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_5 ? T_5 extends […Tail] ? T_5 extends [] ? [] : T_5 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_5 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_6 ? T_6 extends […Tail] ? T_6 extends [] ? [] : T_6 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_6 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_7 ? T_7 extends […Tail] ? T_7 extends [] ? [] : T_7 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_7 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_8 ? T_8 extends […Tail] ? T_8 extends [] ? [] : T_8 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_8 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_9 ? T_9 extends […Tail] ? T_9 extends [] ? [] : T_9 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_9 extends [infer Head_1, …infer Tail] ? […Tail] extends infer T_10 ? T_10 extends […Tail] ? T_10 extends [] ? [] : T_10 extends [infer Head] ? [GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head_1>, GetSuspenseResults<Head>] : T_10 extends [infer Head_1, …infer Tail] ? any : T_10 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_9 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_8 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_7 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_6 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_5 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_4 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_3 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_2 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T_1 extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[] : never : never : T extends UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>[] ? UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>[] : UseSuspenseQueryResult<unknown, unknown>[];
```

Currently, the return type is inferred for complex types.

## Improvement

```ts
// useSuspenseQueries.ts
export function useSuspenseQueries<T extends any[]>({
  queries,
  context,
}: {
  queries: readonly [...SuspenseQueriesOptions<T>]
  context?: UseQueryOptions['context']
}): SuspenseQueriesResults<T> {
  return useQueries({
    queries: queries.map((query: typeof queries) => ({ ...query, suspense: true })),
    context,
  }) as SuspenseQueriesResults<T>
}
```

Specify the return type explicitly to prevent TypeScript’s inference
from hanging.

```ts
// build -> dist/useSuspenseQueries.d.ts
/**
 * SuspenseQueriesResults reducer recursively maps type param to results
 */
type SuspenseQueriesResults<T extends Array<any>, TResult extends Array<any> = [], TDepth extends ReadonlyArray<number> = []> = TDepth['length'] extends MAXIMUM_DEPTH ? Array<UseSuspenseQueryResult> : T extends [] ? [] : T extends [infer Head] ? [...TResult, GetSuspenseResults<Head>] : T extends [infer Head, ...infer Tail] ? SuspenseQueriesResults<[...Tail], [...TResult, GetSuspenseResults<Head>], [...TDepth, 1]> : T extends Array<UseSuspenseQueryOptions<infer TQueryFnData, infer TError, infer TData, any>> ? Array<UseSuspenseQueryResult<unknown extends TData ? TQueryFnData : TData, TError>> : Array<UseSuspenseQueryResult>;
declare function useSuspenseQueries<T extends any[]>({ queries, context, }: {
    queries: readonly [...SuspenseQueriesOptions<T>];
    context?: UseQueryOptions['context'];
}): SuspenseQueriesResults<T>;

export { type SuspenseQueriesOptions, type SuspenseQueriesResults, useSuspenseQueries };
```

The complex inference process is replaced with `SuspenseQueriesResults`,
simplifying it and preventing the TypeScript engine from hanging.

## PR Checklist

- [x] I did below actions if need

1. I read the [Contributing
Guide](https://github.com/suspensive/react/blob/main/CONTRIBUTING.md)
2. I added documents and tests.

---------

Co-authored-by: Jonghyeon Ko <jonghyeon@toss.im>
manudeli added a commit that referenced this pull request Aug 3, 2024
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @suspensive/react@2.0.5

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-await@0.0.19

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-image@0.0.13

### Patch Changes

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

## @suspensive/react-query@2.0.5

### Patch Changes

- [#911](#911)
[`c6c0640`](c6c0640)
Thanks [@gwansikk](https://github.com/gwansikk)! - fix(react-query):
improved TypeScript engine halt due to return type inference in
useSuspenseQueries

- [#912](#912)
[`0c86892`](0c86892)
Thanks [@manudeli](https://github.com/manudeli)! - chore(\*): suspensive
with toss

- Updated dependencies
\[[`0c86892`](0c86892)]:
    -   @suspensive/react@2.0.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: useSuspenseQueries make TypeScript engine boom
3 participants