@skapxd/result
v1.0.1
Published
Type-safe error handling for TypeScript, inspired by Rust
Maintainers
Readme
@skapxd/result
🛡️ Type-safe error handling for TypeScript, inspired by Rust.
Stop throwing exceptions. Start returning results.
This library provides a lightweight Result type and a trySafe utility to handle synchronous and asynchronous operations without try/catch hell.
📦 Installation
npm install @skapxd/result
# or
pnpm add @skapxd/result
# or
yarn add @skapxd/result🚀 Features
- Zero dependencies: Lightweight and fast.
- Type-safe: Built with strict TypeScript configuration.
- Rust-inspired: Use
OkandErrsemantics. - Pattern Matching Ready: Designed to work perfectly with
ts-pattern. - Universal: Works in Node.js, Deno, Bun, and Browsers (ESM & CJS).
💡 Usage
1. Basic Usage (Result)
import { Result } from '@skapxd/result';
function divide(a: number, b: number): Result<number, string> {
if (b === 0) {
return Result.err('Cannot divide by zero');
}
return Result.ok(a / b);
}
const outcome = divide(10, 0);
if (Result.isOk(outcome)) {
console.log('Result:', outcome.value); // TS infers 'number'
} else {
console.error('Error:', outcome.error); // TS infers 'string'
}2. Safer Execution (trySafe)
Wrap risky operations (like parsing JSON or fetching data) to automatically catch errors.
import { trySafe } from '@skapxd/result';
// Synchronous
const jsonResult = trySafe(() => JSON.parse('{"valid": false}'));
// Asynchronous
const apiResult = await trySafe(async () => {
const response = await fetch('/api/user');
if (!response.ok) throw new Error('Network error');
return response.json();
});
if (Result.isErr(apiResult)) {
console.error('Failed to fetch:', apiResult.error);
return;
}
console.log('User data:', apiResult.value);3. Professional Error Modeling (Best Practice)
Avoid "magic strings". Define your errors as Discriminated Unions. This gives you autocompletion and allows you to attach metadata to specific errors.
import { Result } from '@skapxd/result';
import { match } from 'ts-pattern';
// 1. Define your specific error types
type ApiError =
| { type: 'NOT_FOUND'; resource: string }
| { type: 'UNAUTHORIZED'; reason: string }
| { type: 'SERVER_ERROR' };
// 2. Use Result with your error type
function getUser(id: string): Result<User, ApiError> {
if (!id) return Result.err({ type: 'NOT_FOUND', resource: 'User' });
if (!isValid(id)) return Result.err({ type: 'UNAUTHORIZED', reason: 'Bad Token' });
return Result.ok({ id, name: 'Alice' });
}
// 3. Handle it safely with pattern matching
const message = match(getUser('123'))
.with({ ok: true }, ({ value }) => `Hello ${value.name}`)
// TypeScript knows 'resource' exists only on NOT_FOUND
.with({ ok: false, error: { type: 'NOT_FOUND' } }, ({ error }) => `${error.resource} missing`)
// TypeScript knows 'reason' exists only on UNAUTHORIZED
.with({ ok: false, error: { type: 'UNAUTHORIZED' } }, ({ error }) => `Auth failed: ${error.reason}`)
// Catch-all for other errors
.with({ ok: false }, () => 'Something went wrong')
.exhaustive();🛠️ Development
This project uses pnpm (recommended) or npm.
Commands
npm run build: Compiles the package usingtsup(ESM + CJS).npm run test: Runs unit and integration tests.npm run test:ui: Opens the interactive Vitest UI.npm run test:unit: Runs only unit tests (fast).npm run test:integration: Builds the package and runs integration tests againstdist.npm run report:coverage: View HTML coverage report.
📄 License
MIT
