Skip to content
← Dist
typescript+match-fetchtypescriptmatch-fetch

match-fetch consumer examples

How a TypeScript app uses @danrabydev/match-fetch: UserApi extends ApiBase, exhaustive FetchResult.match, and getJson. EXAMPLE_API_TOKEN is an optional env name; example.com is not a live API.

typescriptapp/src/api/users.ts
import {
  ApiBase,
  FetchResult,
  Json,
  isHttpErr,
  type ApiBaseOptions,
  type FetchResult as FetchResultOf,
  type Json as JsonOf,
} from "@danrabydev/match-fetch";

export type User = { id: string; name: string };
export type NewUser = { name: string };

export class UserApi extends ApiBase<{ region: string }> {
  constructor(readonly region: string, options: ApiBaseOptions = {}) {
    super({
      baseUrl: "https://{region}.example.com",
      ...options,
    });
  }

  user(id: string): Promise<FetchResultOf<User>> {
    return this.get("/users/{id}", {
      params: { region: this.region, id },
    });
  }

  create(body: NewUser): Promise<FetchResultOf<User>> {
    return this.post("/users", body, {
      params: { region: this.region },
    });
  }

  userJson(id: string): Promise<JsonOf<User>> {
    return this.getJson("/users/{id}", {
      params: { region: this.region, id },
    });
  }
}

export function handleUser(result: FetchResultOf<User>): string {
  return FetchResult.match(result, {
    Ok: ({ body }) => body.name,
    Created: ({ body }) => body.name,
    NoContent: () => "",
    Conflict: ({ status }) => `conflict ${status}`,
    ClientError: ({ status }) => `client ${status}`,
    ServerError: ({ status }) => `server ${status}`,
    Other: ({ status }) => `other ${status}`,
    NetworkError: ({ err }) => `network: ${String(err)}`,
    ParseError: ({ err }) => `parse: ${String(err)}`,
  });
}

export function handleUserJson(result: JsonOf<User>): string {
  return Json.match(result, {
    Ok: ({ body }) => body.name,
    Err: ({ err }) =>
      isHttpErr(err) ? `http ${err.status}` : `err: ${String(err)}`,
  });
}