Skip to content

Commit 72cc8dd

Browse files
jacquesgkettanaito
andauthored
fix(TypeScript): support Response.error() and HttpResponse.error() as mocked responses (#2132)
Co-authored-by: Artem Zakharchenko <[email protected]>
1 parent d38097f commit 72cc8dd

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

src/core/HttpResponse.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ export interface HttpResponseInit extends ResponseInit {
1010
type?: ResponseType
1111
}
1212

13-
const bodyType: unique symbol = Symbol('bodyType')
13+
export const bodyType: unique symbol = Symbol('bodyType')
14+
export type DefaultUnsafeFetchResponse = Response & {
15+
[bodyType]?: never
16+
}
1417

1518
export interface StrictRequest<BodyType extends JsonBodyType> extends Request {
1619
json(): Promise<BodyType>
@@ -46,6 +49,10 @@ export class HttpResponse<
4649
decorateResponse(this, responseInit)
4750
}
4851

52+
static error(): HttpResponse<any> {
53+
return super.error() as HttpResponse<any>
54+
}
55+
4956
/**
5057
* Create a `Response` with a `Content-Type: "text/plain"` body.
5158
* @example

src/core/handlers/RequestHandler.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@ import {
66
} from '../utils/internal/isIterable'
77
import type { ResponseResolutionContext } from '../utils/executeHandlers'
88
import type { MaybePromise } from '../typeUtils'
9-
import type { HttpResponse, StrictRequest } from '..//HttpResponse'
9+
import {
10+
StrictRequest,
11+
HttpResponse,
12+
DefaultUnsafeFetchResponse,
13+
} from '../HttpResponse'
1014
import type { HandlerKind } from './common'
15+
import type { GraphQLRequestBody } from './GraphQLHandler'
1116

1217
export type DefaultRequestMultipartBody = Record<
1318
string,
@@ -42,9 +47,19 @@ export interface RequestHandlerInternalInfo {
4247
export type ResponseResolverReturnType<
4348
ResponseBodyType extends DefaultBodyType = undefined,
4449
> =
50+
// If ResponseBodyType is a union and one of the types is `undefined`,
51+
// allow plain Response as the type.
4552
| ([ResponseBodyType] extends [undefined]
4653
? Response
47-
: HttpResponse<ResponseBodyType>)
54+
: /**
55+
* Treat GraphQL response body type as a special case.
56+
* For esome reason, making the default HttpResponse<T> | DefaultUnsafeFetchResponse
57+
* union breaks the body type inference for HTTP requests.
58+
* @see https://github.com/mswjs/msw/issues/2130
59+
*/
60+
ResponseBodyType extends GraphQLRequestBody<any>
61+
? HttpResponse<ResponseBodyType> | DefaultUnsafeFetchResponse
62+
: HttpResponse<ResponseBodyType>)
4863
| undefined
4964
| void
5065

test/typings/graphql.test-d.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,23 @@ it('graphql handlers allow passthrough responses', () => {
157157
})
158158
})
159159

160+
it('supports Response.error()', () => {
161+
graphql.query<{ id: string }>('GetUser', () => HttpResponse.error())
162+
graphql.mutation('UpdatePost', () => HttpResponse.error())
163+
graphql.operation(() => HttpResponse.error())
164+
165+
graphql.query('GetUser', async () => HttpResponse.error())
166+
graphql.query('GetUser', function* () {
167+
return HttpResponse.error()
168+
})
169+
170+
graphql.query('GetUser', () => Response.error())
171+
graphql.query('GetUser', async () => Response.error())
172+
graphql.query('GetUser', function* () {
173+
return Response.error()
174+
})
175+
})
176+
160177
it("graphql variables cannot extract type from the runtime 'DocumentNode'", () => {
161178
/**
162179
* Supports `DocumentNode` as the GraphQL operation name.

test/typings/http.test-d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,17 @@ it('treats non-typed HttpResponse body type as matching', () => {
295295
return new HttpResponse(null, { status: 500 })
296296
})
297297
})
298+
299+
it('supports returning Response.error()', () => {
300+
http.get('/resource', () => Response.error())
301+
http.get('/resource', async () => Response.error())
302+
http.get('/resource', function* () {
303+
return Response.error()
304+
})
305+
306+
http.get<never, never, string>('/resource', () => HttpResponse.error())
307+
http.get<never, never, string>('/resource', async () => HttpResponse.error())
308+
http.get<never, never, string>('/resource', function* () {
309+
return HttpResponse.error()
310+
})
311+
})

0 commit comments

Comments
 (0)