better-result — TypeScript向け軽量 Result 型(ジェネレータ合成)

Library

概要

better-result は、TypeScript でエラー処理を明示化するための軽量な Result 型ライブラリです。Rust の Result 型に似た Ok/Err の二形態を提供し、例外を Result に包んで扱う Result.try、成功失敗を分岐する match、簡易チェック用の isOk/isErr といった API を備えています。注目点は「ジェネレータベースの合成」をサポートしている点で、ジェネレータ内で yield した Result を逐次評価し、最初に遭遇した Err を即座に返すことでネストの深いエラーチェックを平坦化します。依存をほぼ持たずに導入でき、型安全なエラーハンドリングを簡潔に記述できるのが利点です。(約300字)

GitHub

リポジトリの統計情報

  • スター数: 27
  • フォーク数: 0
  • ウォッチャー数: 27
  • コミット数: 2
  • ファイル数: 9
  • メインの言語: TypeScript

主な特徴

  • Ok/Err の Result 型と便利なユーティリティ(try, isOk, match 等)を提供
  • ジェネレータ関数を使った合成(do-notation ライク)で早期リターンを実現
  • 非同期/同期のコードに適用しやすいシンプルな API と型推論の良さ
  • 依存が少なく軽量で、プロダクション導入のハードルが低い

技術的なポイント

better-result の技術的な核は「小さな API で Result パターンを TypeScript に落とし込む」ことと、「ジェネレータを利用した合成」にあります。Result.try は任意の例外を投げる関数を包んで Ok/Err に変換するユーティリティで、JSON.parse のような例外発生源を安全に扱えます。Result.match はパターンマッチ風に成功時と失敗時のハンドラを分離して記述でき、分岐ロジックが明瞭になります。

特に注目すべきはジェネレータベースの合成機能です。ジェネレータ内で yield によって Result を返す形にすると、内部のロジックは逐次的に書ける一方で、最初に返ってきた Err によって処理を中断して呼び出し元に Err を返す「早期帰還」パターンがほぼ自動化されます。これは Rust の ? 演算子や Haskell の do-notation に相当する使い勝手を TypeScript で提供するアイデアで、ネストした if/else や複数のエラーチェックを平坦に記述できます。

実装面では TypeScript の高度な型推論を活かし、ジェネリックな Result<T, E> 型を導入しており、Ok 領域の値型や Err の型情報を呼び出し元に伝搬させるよう設計されています。ランタイムは非常に軽く、外部依存を増やさずに済むためバンドルサイズや複雑さの点で有利です。API は同期的な関数だけでなく、ジェネレータを介して非同期的なフローの簡潔化にも寄与するため、async/await と組み合わせた設計も考慮できます(実装の具合により扱い方は多少異なります)。また README にある Quick Start の通り導入が容易で、既存のエラーハンドリングを段階的に置き換えられる点も実務的メリットです。(約1800字)

プロジェクトの構成

主要なファイルとディレクトリ:

  • .gitignore: file
  • AGENTS.md: file
  • LICENSE: file
  • README.md: file
  • bun.lock: file

…他 4 ファイル

(README からの抜粋)

better-result

Lightweight Result type for TypeScript with generator-based composition.

Install

npm install better-result

Quick Start

import { Result } from "better-result";

// Wrap throwing functions
const parsed = Result.try(() => JSON.parse(input));

// Check and use
if (Result.isOk(parsed)) {
  console.log(parsed.value);
} else {
  console.error(parsed.error);
}

// Or use pattern matching
const message = parsed.match({
  ok: (data) => `Got: ${data.name}`,
  err:...

まとめ

シンプルで導入しやすく、ジェネレータ合成による実用的な早期リターンを提供する軽量 Result ライブラリです。(約50字)

リポジトリ情報: