http
HTTP method, status code, content-type, and request/response shape types.
import type {
HttpMethod, SafeMethod, IdempotentMethod,
IsSafeMethod, IsIdempotentMethod,
Informational, Success, Redirection, ClientError, ServerError,
HttpStatusCode, StatusFamily,
IsSuccess, IsClientError, IsServerError,
ContentType,
HttpRequestShape, HttpResponseShape,
} from '@gentleduck/ttest/http'
Curated HTTP unions and helpers. Constrain client and server APIs to valid methods, status codes, and content types without rolling per-endpoint enums.
HttpMethod
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE'
Every standard method per RFC 9110.
SafeMethod
type SafeMethod = 'GET' | 'HEAD' | 'OPTIONS' | 'TRACE'
Methods that must not modify server state. SafeMethod ⊂ IdempotentMethod ⊂ HttpMethod.
IdempotentMethod
type IdempotentMethod = 'GET' | 'HEAD' | 'OPTIONS' | 'TRACE' | 'PUT' | 'DELETE'
Methods whose repeated invocation has the same effect as a single one — safe to retry.
IsSafeMethod
type IsSafeMethod<M extends HttpMethod> = M extends SafeMethod ? true : false
type a = IsSafeMethod<'GET'> // true
type b = IsSafeMethod<'POST'> // false
IsIdempotentMethod
type IsIdempotentMethod<M extends HttpMethod> = M extends IdempotentMethod ? true : false
type a = IsIdempotentMethod<'PUT'> // true
type b = IsIdempotentMethod<'POST'> // false
Informational
type Informational = 100 | 101 | 102 | 103
1xx status codes.
Success
type Success = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226
2xx status codes.
Redirection
type Redirection = 300 | 301 | 302 | 303 | 304 | 305 | 307 | 308
3xx status codes.
ClientError
type ClientError = 400 | 401 | 402 | ... | 451
4xx status codes — every code IANA currently assigns.
ServerError
type ServerError = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511
5xx status codes.
HttpStatusCode
type HttpStatusCode = Informational | Success | Redirection | ClientError | ServerError
Union of every standard status code.
StatusFamily
type StatusFamily<S extends HttpStatusCode>
Grouping label — one of '1xx' | '2xx' | '3xx' | '4xx' | '5xx'.
type a = StatusFamily<200> // '2xx'
type b = StatusFamily<404> // '4xx'
type c = StatusFamily<503> // '5xx'
IsSuccess
type IsSuccess<S extends HttpStatusCode> = S extends Success ? true : false
type a = IsSuccess<200> // true
type b = IsSuccess<404> // false
IsClientError
type IsClientError<S extends HttpStatusCode> = S extends ClientError ? true : false
IsServerError
type IsServerError<S extends HttpStatusCode> = S extends ServerError ? true : false
type a = IsServerError<500> // true
type b = IsServerError<200> // false
ContentType
type ContentType = 'application/json' | 'text/html' | 'image/png' | ...
Common MIME types. Widen to string if you serve unusual ones.
HttpRequestShape
interface HttpRequestShape<M extends HttpMethod = HttpMethod, Body = unknown> {
method: M
headers?: Record<string, string>
body?: Body
}
Minimal request descriptor — useful in type-safe client builders.
function send<B>(req: HttpRequestShape<'POST', B>): Promise<Response> { /* ... */ }
send({ method: 'POST', body: { id: 1 } })
HttpResponseShape
interface HttpResponseShape<S extends HttpStatusCode = HttpStatusCode, Body = unknown> {
status: S
headers?: Record<string, string>
body: Body
}
Minimal response descriptor. Pair with StatusFamily to type-narrow handlers.
function handle<S extends HttpStatusCode>(res: HttpResponseShape<S>): StatusFamily<S> {
return (`${Math.floor(res.status / 100)}xx`) as StatusFamily<S>
}
Edge case: every status union is a literal-number set. 404 satisfies HttpStatusCode works; Number('404') satisfies HttpStatusCode does not — call sites typically need as const on numeric literals or an explicit annotation.