Skip to content

Commit a9d23a4

Browse files
authored
fix: Make serverFn union response type distributive (#5720)
1 parent 19ae762 commit a9d23a4

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

packages/start-client-core/src/createServerFn.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,11 @@ export type RscStream<T> = {
301301
export type Method = 'GET' | 'POST'
302302

303303
export type ServerFnReturnType<TRegister, TResponse> =
304-
Awaited<TResponse> extends Response
305-
? TResponse
306-
: ValidateSerializableInput<TRegister, TResponse>
304+
TResponse extends PromiseLike<infer U>
305+
? Promise<ServerFnReturnType<TRegister, U>>
306+
: TResponse extends Response
307+
? TResponse
308+
: ValidateSerializableInput<TRegister, TResponse>
307309

308310
export type ServerFn<
309311
TRegister,

packages/start-client-core/src/tests/createServerFn.test-d.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ import type {
66
Constrain,
77
Register,
88
TsrSerializable,
9+
ValidateSerializableInput,
910
Validator,
1011
} from '@tanstack/router-core'
11-
import type { ConstrainValidator } from '../createServerFn'
12+
import type {
13+
ConstrainValidator,
14+
ServerFnReturnType,
15+
} from '../createServerFn'
1216

1317
test('createServerFn method with autocomplete', () => {
1418
createServerFn().handler((options) => {
@@ -308,7 +312,10 @@ test('createServerFn returns Date', () => {
308312
dates: [new Date(), new Date()] as const,
309313
}))
310314

311-
expectTypeOf(fn()).toEqualTypeOf<Promise<{ dates: readonly [Date, Date] }>>()
315+
expectTypeOf<ReturnType<typeof fn>>().toMatchTypeOf<Promise<unknown>>()
316+
expectTypeOf<Awaited<ReturnType<typeof fn>>>().toMatchTypeOf<
317+
ValidateSerializableInput<Register, { dates: readonly [Date, Date] }>
318+
>()
312319
})
313320

314321
test('createServerFn returns undefined', () => {
@@ -379,6 +386,23 @@ describe('response', () => {
379386

380387
expectTypeOf(fn()).toEqualTypeOf<Promise<Response>>()
381388
})
389+
390+
test(`client receives union when handler may return Response or string`, () => {
391+
const fn = createServerFn().handler(() => {
392+
const result: Response | 'Hello World' =
393+
Math.random() > 0.5 ? new Response('Hello World') : 'Hello World'
394+
395+
return result
396+
})
397+
398+
expectTypeOf(fn()).toEqualTypeOf<Promise<Response | 'Hello World'>>()
399+
})
400+
})
401+
402+
test('ServerFnReturnType distributes Response union', () => {
403+
expectTypeOf<
404+
ServerFnReturnType<Register, Response | 'Hello World'>
405+
>().toEqualTypeOf<Response | 'Hello World'>()
382406
})
383407

384408
test('createServerFn can be used as a mutation function', () => {

0 commit comments

Comments
 (0)