Skip to content

Custom Envelope

By default, expect-status reads status and body from the response object. If your API uses different field names, configure them with statusField and bodyField.

import { createExpectStatus } from "expect-status";
const expectStatus = createExpectStatus({
statusField: "code",
bodyField: "payload",
});
type Response =
| { code: 200; payload: { id: string; name: string } }
| { code: 404; payload: { message: string } };
const item = await expectStatus(200, response);
// ^? { id: string; name: string }
const expectStatus = createExpectStatus({
statusField: "statusCode",
bodyField: "data",
});
type Response =
| { statusCode: 200; data: { id: string } }
| { statusCode: 404; data: { message: string } };

statusField and bodyField read top-level fields only. For deeply nested structures, use adapter instead — it receives the raw response and returns a normalised { status, body }:

const expectStatus = createExpectStatus({
adapter: (res) => ({
status: res.meta.httpStatus,
body: res.result.data,
}),
});

When adapter is provided, statusField and bodyField are ignored.

If you don’t use adapter, flatten manually before passing:

async function callApi(response: NestedResponse) {
return expectStatus(200, {
status: response.meta.code,
body: response.result.data,
});
}

TypeScript correctly infers field names throughout — handler bodies are still typed per branch:

const expectStatus = createExpectStatus({
statusField: "code",
bodyField: "result",
});
type Response =
| { code: 200; result: { id: string } }
| { code: 404; result: { message: string } };
await expectStatus(200, response, {
404: (body) => {
body.message; // typed as string
},
});