Open3

API のレスポンスにステータスコード別の型を付与する

SUWA ShigekiSUWA Shigeki
lib.dom.d.ts
interface Response extends Body {
    readonly headers: Headers;
    readonly ok: boolean;
    readonly redirected: boolean;
    readonly status: number;
    readonly statusText: string;
    readonly type: ResponseType;
    readonly url: string;
    clone(): Response;
}
lib.dom.d.ts
interface Body {
    readonly body: ReadableStream<Uint8Array> | null;
    readonly bodyUsed: boolean;
    arrayBuffer(): Promise<ArrayBuffer>;
    blob(): Promise<Blob>;
    formData(): Promise<FormData>;
    json(): Promise<any>;
    text(): Promise<string>;
}
SUWA ShigekiSUWA Shigeki
interface JsonResponse<Status extends number, Body> extends Response {
  readonly status: Status
  arrayBuffer(): Promise<never>;
  blob(): Promise<never>;
  formData(): Promise<never>;
  json(): Promise<Body>;
  text(): Promise<never>;
}
type OkResponse = JsonResponse<200, { foo: string }>
type ErrorResponse = JsonResponse<400, { errors: string[] }>

const response = await fetch("https://example.com") as OkResponse | ErrorResponse

switch (response.status) {
  case 200: {
    const { foo } = await response.json()
  }
  case 400: {
    const { errors } = await response.json()
  }
}
SUWA ShigekiSUWA Shigeki

外からくる値に as で型付けするので、信頼できるサーバでなければzodとかは必要