Skip to content

[Feature] HttpStatus branded type with range validation #281

@pathosDev

Description

@pathosDev

Size / Priority

  • Size: Trivial (~50 lines)
  • Category: C.3 Type-Safety.
  • Risk: low.

Affected files

  • src/http/types.tsStatus enum.

Background

HTTP status codes are number literals (200, 404, 500). Easy to mix up:

  • 200 vs 204 (No Content) vs 201 (Created).
  • 301 (Moved Permanently) vs 302 (Found) vs 307 (Temporary Redirect).

A branded HttpStatus with range validation + named constants:

declare const HTTP_STATUS_BRAND: unique symbol;
export type HttpStatus = number & { readonly [HTTP_STATUS_BRAND]: true };

export function httpStatus(n: number): HttpStatus {
  if (!Number.isInteger(n) || n < 100 || n > 599) {
    throw new Error(`invalid HTTP status: ${n}`);
  }
  return n as HttpStatus;
}

// Named constants
export const Status = {
  OK: httpStatus(200),
  Created: httpStatus(201),
  NoContent: httpStatus(204),
  Found: httpStatus(302),
  BadRequest: httpStatus(400),
  Unauthorized: httpStatus(401),
  Forbidden: httpStatus(403),
  NotFound: httpStatus(404),
  InternalServerError: httpStatus(500),
  // ...
} as const;

Integration / risk

  • API change for HttpResponse.status.
  • Minimal disruption.

Test plan

  1. Status constants work.
  2. Invalid range rejected.

Acceptance criteria

  • httpStatus(n) smart constructor.
  • Status constants.
  • Range validation.
  • No CHANGELOG entry needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: lowNice-to-have / niche / demand-driven

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions