🐳
Result型のライブラリを作りました【TypeScript】
Rust, Kotlin, Swiftなどのモダンな言語ではいわゆるResult型が標準で提供されていますがTypeScriptにはありません。
既にいくつものResult型のnpmパッケージが公開されているのですが、自分好みのものが見当たらなかったので自作しました。
設計上の工夫
TypeScriptでは型と同名の名前空間を両立して定義できます。
この仕様を使って型(export type Result
)と名前空間(export namespace Result
)の両方を定義し、ヘルパー関数などは全て名前空間の中に配置しました。
そのおかげでResult
だけをimportすれば済みますし、関数名などを覚えていなくてもエディターの候補表示から全てのユーティリティを辿れるようになっています。
こういう設計にするとTree shakingが効かなくなってしまうのですが、Result型だけの小さなライブラリなので普通のプロジェクトではバンドルサイズはほとんど誤差になってメリットの方が上回るのではないかと考えました。
使い方
↑のnpmパッケージをインストールして、以下のような感じで使えます。
import { Result } from 'result-type-ts'
const result = Math.random() < 0.5 ? Result.success(123) : Result.failure('error')
// 条件分岐しなくても内部の値を取得できます
console.log(result.value) // 123 または undefined
console.log(result.error) // undefined または 'error'
if (result.isSuccess) {
// result.valueの型はnumber | undefinedからnumberにナローイングされます
console.log(result.value)
} else {
// 同じくresult.errorはstring型にナローイングされます
console.log(result.error)
}
幅広いユースケースに対応するため、Result関連のユーティリティをたくさん収録してあります。
この記事は単なる紹介記事なので、関数などの名前の一覧だけ掲載しておきます。
ちゃんとしたドキュメントはREADME内にあります。
関数
Result.success(value)
Result.failure(error)
Result.tryCatch(f)
Result.fromNullish(value)
Result.fromPromise(promise)
Result.all(results)
型
Result.Success<T>
Result.Failure<E>
Result<T, E>
プロパティ
result.value
result.error
result.isSuccess
result.isFailure
メソッド
result.getOrThrow()
result.toUnion()
result.ifSuccess(f)
result.ifFailure(f)
result.match(f, g)
result.map(f)
result.mapError(f)
result.flatMap(f)
result.flatten()
result.assertErrorInstanceOf(constructor)
以上です!
ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion