Type-Level Patterns
expect-status exports several TypeScript types for advanced type-level programming and custom utilities.
ResolveSuccessBody
Section titled “ResolveSuccessBody”Extracts the body type for the matching success status.
import type { ResolveSuccessBody } from "expect-status";
type Response = | { status: 200; body: { id: string } } | { status: 201; body: { id: string; created: boolean } } | { status: 404; body: { message: string } };
type Body200 = ResolveSuccessBody<Response, 200>;// ^? { id: string }
type Body200or201 = ResolveSuccessBody<Response, [200, 201]>;// ^? { id: string } | { id: string; created: boolean }SuccessArg
Section titled “SuccessArg”Constrains the success status argument to valid status codes from the response type.
import type { SuccessArg } from "expect-status";
type Response = | { status: 200; body: { id: string } } | { status: 404; body: { message: string } };
type ValidSuccess = SuccessArg<Response, "status">;// ^? 200 | 404 | readonly (200 | 404)[]ResolveErrorStatus
Section titled “ResolveErrorStatus”Extracts the error statuses (non-success) from a response type. Works with single or array success arguments.
import type { ResolveErrorStatus } from "expect-status";
type Response = | { status: 200; body: { id: string } } | { status: 404; body: { message: string } } | { status: 409; body: { message: string } };
type Errors = ResolveErrorStatus<Response, 200>;// ^? 404 | 409
type MultiErrors = ResolveErrorStatus<Response, readonly [200]>;// ^? 404 | 409StatusToClass
Section titled “StatusToClass”Maps three-digit statuses to their HTTP class.
import type { StatusToClass } from "expect-status";
type Class200 = StatusToClass<200>;// ^? '2xx'
type Class404 = StatusToClass<404>;// ^? '4xx'
type Class500 = StatusToClass<500>;// ^? '5xx'IsCovered
Section titled “IsCovered”Type-level check for whether a numeric status is covered by an exact match in Keys or by its class-level range being in Keys.
import type { IsCovered } from "expect-status";
type Covered = IsCovered<200, 200 | 404>;// ^? true
type NotCovered = IsCovered<409, 200 | 404>;// ^? false
type RangeCovered = IsCovered<404, 200 | "4xx">;// ^? true (404 falls under '4xx')UncoveredErrors
Section titled “UncoveredErrors”Lists error statuses that are not covered by a set of handler/message keys.
import type { UncoveredErrors } from "expect-status";
type Response = | { status: 200; body: { id: string } } | { status: 404; body: { message: string } } | { status: 409; body: { message: string } };
// Success is 200, keys cover only 404 — 409 is uncoveredtype Uncovered = UncoveredErrors<Response, 200, 404>;// ^? 409
// '4xx' range covers both 404 and 409type AllCovered = UncoveredErrors<Response, 200, "4xx">;// ^? neverExhaustiveCheck
Section titled “ExhaustiveCheck”Resolves to boolean if all error statuses are covered (allowing exhaustive: true). Otherwise resolves to a branded error object naming the missing codes.
import type { ExhaustiveCheck } from "expect-status";
type Response = | { status: 200; body: { id: string } } | { status: 404; body: { message: string } } | { status: 409; body: { message: string } };
type NotExhaustive = ExhaustiveCheck<Response, 200, 404>;// ^? { __expectStatusError: '...'; missing: 409 }
type Exhaustive = ExhaustiveCheck<Response, 200, 404 | 409>;// ^? booleanCustom type utilities
Section titled “Custom type utilities”You can use these types to build custom type-level utilities:
import type { ResolveSuccessBody, ResolveErrorStatus } from "expect-status";
type ApiClient<R, S> = { request<T>(path: string): Promise<ResolveSuccessBody<R, S>>; errors: ResolveErrorStatus<R, S>;};
type MyClient = ApiClient< | { status: 200; body: { id: string } } | { status: 404; body: { message: string } }, 200>;
// MyClient.errors = 404See also
Section titled “See also”- Types API — full type reference
- Exhaustive Checking — compile-time coverage