Adds safeRet() functionality to Ok & Err
npm install neverthrow-safe-retneverthrow to provide a Go-inspired error-handling pattern while maintaining strict type safety. If you’ve ever wanted to destructure a Result into a [error, value] tuple without losing type information, this is for you.
[err, value] destructuring with type inference.
neverthrow, no bloat.
.safeRet() directly to Result instances.
undefined narrowing.
neverthrow code.
bash
npm install neverthrow-safe-ret
`
---
Why?
The original neverthrow issue \#614 highlights the friction of chaining .andThen() for sequential operations. This library solves it by:
1. Letting you exit early on errors without callback hell.
2. Inferring types after checks (e.g., value becomes non-undefined post-error guard).
---
Usage
$3
`typescript
import { ok, err } from 'neverthrow';
import 'neverthrow-safe-ret';
const result = ok(42).safeRet();
const [error, value] = result;
if (error) {
// Handle error (type: Error | undefined)
} else {
console.log(value); // Type: number
}
`
$3
`typescript
import { Result, ok, err } from 'neverthrow';
import 'neverthrow-safe-ret';
declare function getUser(id: string): Result;
declare function validate(user: User): Result;
function processUser(id: string): Result {
const [fetchErr, user] = getUser(id).safeRet();
if (fetchErr) return err(fetchErr);
const [validationErr, isValid] = validate(user).safeRet();
if (validationErr) return err(validationErr);
return ok(isValid);
}
`
---
How It Works
The .safeRet() method returns a tuple where:
- Error position: E (undefined if Ok).
- Value position: T (undefined if Err).
Type narrowing example:
`typescript
const [e, s] = ok("string").safeRet();
// e: undefined, s: string
const [e2, s2] = err("error").safeRet();
// e2: "error", s2: undefined
function a(x: Result): Result {
const [e3, s3] = x.safeRet();
// e3: string | undefined, s3: number | undefined
// this forces you to check for e3
if (typeof e3 !== "undefined") {
// here we are sure that e3 is string and s3 is undefined
return err(e3);
}
// s3 is now number
return ok(s3);
}
`
---
Comparison
| Approach | Code Style | Type Safety | Error Checks Enforced |
| :-- | :-- | :-- | :-- |
| Vanilla neverthrow | Method chaining | ✅ | ❌ (via match) |
| neverthrow-safe-ret | Imperative checks | ✅ | ✅ (via undefined) |
---
Caveats
- Monkey-patching: Modifies Result` prototypes. Avoid if your team dislikes patching.