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: accept a narrower response body type by default #2107

Merged
merged 2 commits into from
Mar 25, 2024

Conversation

kettanaito
Copy link
Member

@kettanaito kettanaito commented Mar 25, 2024

Changes

  • HttpResponse.text() and HttpResponse.json() do not infer the given body type anymore. This allows them to correctly infer whichever response body type is set on the wrapping request handler. As a consequence, the response body type will now respect the narrower type provided to the handler:
http.get<never, never, { a: number }>('/', () => {
  // Error: Unknown property "b".
  return HttpResponse.json({ a: 1, b: 2 })
})

Previously, this mocked response would satisfy the { a: number } argument.

  • When GraphQL handlers are used without explicit type arguments for the query/variables, those generic parameters become never even though they have fallback types. To prevent that, we are now explicitly checking for never: GraphQLResponseBody<[Query] extends [never] ? GraphQLQuery : Query>. This makes the GraphQL handlers compatible with the NoInfer changes to HttpResponse.json().
  • Default GraphQL response body now supports null | undefined. It's still technically possible to respond to a GraphQL response with those.
  • Polishes a few type tests to take advantage of type asserting utilities instead of relying on x.toUpperCase() and such.

Warning

With the NoInfer changes to HttpResponse.json(), extra keys in the response body object will cause type errors. You have to explicitly allow (and describe) any extra keys your object may have:

http.get<never, never, { [key: string]: string, a: number }>('/', () => {
  return HttpResponse.json({ a: 1, b: 'hello' })
})

I find this to be a good default because allowing extra keys is far easier than forbidding them in TypeScript. 
  • As a nice side effect of this change, the type errors related to the response body are now displayed in the right place (now next to the actual properties at question; previously, next to the entire response resolver function):
   http.get<{ id: string }, never, 'hello'>(
     '/user/:id',
-    // Previously, errored here.
     withDelay(250, ({ params }) => {
       expectTypeOf(params).toEqualTypeOf<{ id: string }>()
-      return HttpResponse.text('non-matching')
+      return HttpResponse.text(
+        // Now, errors here.
+        'non-matching',
+      )
     }),

@kettanaito kettanaito force-pushed the feat/2105-http-response-no-infer branch from 78ec30b to 228c1b7 Compare March 25, 2024 11:41
@kettanaito kettanaito changed the title fix: respect a narrower request/response body type fix: respect a narrower response body type Mar 25, 2024
@kettanaito kettanaito changed the title fix: respect a narrower response body type fix: accept a narrower response body type by default Mar 25, 2024
@kettanaito kettanaito merged commit d35ef92 into main Mar 25, 2024
12 checks passed
@kettanaito kettanaito deleted the feat/2105-http-response-no-infer branch March 25, 2024 12:53
@kettanaito
Copy link
Member Author

Released: v2.2.11 🎉

This has been released in v2.2.11!

Make sure to always update to the latest version (npm i msw@latest) to get the newest features and bug fixes.


Predictable release automation by @ossjs/release.

@VanTanev
Copy link
Contributor

Something super tangential if someone else reads the code above:

Avoid @ts-expect-error, it's a very bad practice. Using as any is preferable in every situation. @ts-expect-error will destroy errors you actually care about (eg, mistyped method name, wrong number of arguments, etc etc).

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.

Narrowing the response body type in HttpResponse.json
2 participants