Skip to content

fix(types): stop collapsing custom intersection types in createResponse/createMocks#337

Merged
eugef merged 1 commit into
eugef:masterfrom
MGough:fix/createmocks-intersection-type-collapse
Jul 16, 2026
Merged

fix(types): stop collapsing custom intersection types in createResponse/createMocks#337
eugef merged 1 commit into
eugef:masterfrom
MGough:fix/createmocks-intersection-type-collapse

Conversation

@MGough

@MGough MGough commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Since 1.18.0, passing a custom response type to createMocks<T1, T2>() (or createResponse<T2>()) no longer works when T2 is an intersection of a framework type (e.g. Next.js's NextApiResponse) with MockResponse<Response<...>>.

The new conditional return types added in #324 / #323 (to type _getJSONData()) narrow T2 down to a bare express.Response<ResBody> (or globalThis.Response), silently discarding the intended intersection with T2.

I believe those changes weren't needed in order to support the _getJSONData() typing.

This worked correctly in 1.17.2

Reproduction

import { NextApiRequest, NextApiResponse } from "next";
import {
  createMocks as _createMocks,
  createRequest,
  createResponse,
} from "node-mocks-http";

type ApiRequest = NextApiRequest & ReturnType<typeof createRequest>;
type ApiResponse = NextApiResponse & ReturnType<typeof createResponse>;

const createMocks = (...args: Parameters<typeof _createMocks>) =>
  _createMocks<ApiRequest, ApiResponse>(...args);

// elsewhere, in a test:
const { req, res } = createMocks({ method: "GET" });
await someNextApiHandler(req, res); // <-- res no longer typechecks as NextApiResponse

Expected

res is typed as MockResponse<ApiResponse>, i.e. it still includes the NextApiResponse (or whatever custom interface) portion of T2, exactly as it was resolved before 1.18.0.

Actual

res is typed as MockResponse<Response | e.Response<any, Record<string, any>>> (a union of globalThis.Response and express.Response). Passing it anywhere that expects NextApiResponse fails with:

Argument of type 'MockResponse<Response | e.Response<any, Record<string, any>>>' is not assignable to parameter of type 'NextApiResponse'.
  Type '...' is missing the following properties from type 'ServerResponse<IncomingMessage>': statusCode, statusMessage, strictContentLength, assignSocket, and 67 more.

This PR

This PR adds regression tests to both request and response to ensure that support for these custom intersection types are always maintained, and subsequently rolls back the changes to createResponse and createMocks.

@eugef
eugef merged commit 87e0bcb into eugef:master Jul 16, 2026
4 checks passed
@eugef

eugef commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Hi @MGough, thanks for you contribution and especially for the regression tests.
The fix is released in v 1.18.1

@MGough

MGough commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @eugef - I considered opening an issue but the change was small enough and the docs seemed to encourage a PR as a first step so I hope that's OK. Thanks for keeping the project maintained!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants