The Result library is a TypeScript utility that provides a structured way to handle success (Ok
) and failure (Err
) cases in your application. It is inspired by functional programming patterns and languages like Rust, enabling robust error handling without relying on exceptions.
-
Type Safety: Explicitly handle
Ok
andErr
cases with strong TypeScript typings. - Convenient API: Simplifies handling success and error scenarios with intuitive methods.
- Improved Error Handling: Avoid unexpected runtime errors with structured control flows.
- Reusable Components: Easily integrate into any TypeScript project.
npm install result-library
To create Ok
and Err
results, use the ResultBuilder
interface.
import { ResultBuilder } from 'result-library';
const { Ok, Err } = ResultBuilder();
const success = Ok("Operation was successful");
const failure = Err("An error occurred");
if (success.is_ok()) {
console.log("Success:", success.unwrap());
} else {
console.error("Error:", success.err());
}
if (failure.is_err()) {
console.error("Failure:", failure.unwrap_err());
}
function divide(a: number, b: number) {
const { Ok, Err } = ResultBuilder();
if (b === 0) {
return Err("Division by zero is not allowed");
}
return Ok(a / b);
}
const result = divide(10, 2);
if (result.is_ok()) {
console.log("Result:", result.unwrap());
} else {
console.error("Error:", result.unwrap_err());
}
You can define explicit types for better type safety.
const { Ok, Err } = ResultBuilder<number, string>();
const result = Ok(42);
const error = Err("Something went wrong");
if (result.is_ok()) {
console.log(result.unwrap());
} else {
console.error(result.unwrap_err());
}
function fetchUserData(userId: string) {
const { Ok, Err } = ResultBuilder<{ name: string; age: number }, string>();
if (userId === "123") {
return Ok({ name: "John Doe", age: 30 });
} else {
return Err("User not found");
}
}
const userResult = fetchUserData("123");
if (userResult.is_ok()) {
console.log("User Data:", userResult.unwrap());
} else {
console.error("Error:", userResult.unwrap_err());
}
function processFile(filePath: string) {
const { Ok, Err } = ResultBuilder<string, string>();
if (!filePath.endsWith(".txt")) {
return Err("Only .txt files are supported");
}
try {
const fileContent = "File content"; // Simulate reading a file
return Ok(fileContent);
} catch (error) {
return Err("Failed to process the file");
}
}
const fileResult = processFile("example.txt");
if (fileResult.is_ok()) {
console.log("File Content:", fileResult.unwrap());
} else {
console.error("Error:", fileResult.unwrap_err());
}
async function fetchData(apiUrl: string) {
const { Ok, Err } = ResultBuilder<any, string>();
try {
const response = await fetch(apiUrl);
if (!response.ok) {
return Err(`API error: ${response.status}`);
}
const data = await response.json();
return Ok(data);
} catch (error) {
return Err("Network error");
}
}
(async () => {
const apiResult = await fetchData("https://api.example.com/data");
if (apiResult.is_ok()) {
console.log("API Data:", apiResult.unwrap());
} else {
console.error("Error:", apiResult.unwrap_err());
}
})();
The Result
class provides a way to handle success and error outcomes in a structured way. Below is an example demonstrating how to use Ok
, Err
, and the ResultBuilder
to handle different results.
import { ResultBuilder } from 'result-library';
// deconstruct ResultBuilder and create Ok, Err builder instance
const { Ok, Err } = ResultBuilder<string, string>();
// Simulate a function that can either succeed or fail
function fetchData(success: boolean) {
if (success) {
return Ok('Data retrieved successfully');
} else {
return Err('Failed to retrieve data');
}
}
// Simulate a success scenario
const successResult = fetchData(true);
if (successResult.is_ok()) {
console.log(successResult.ok()); // Output: 'Data retrieved successfully'
} else {
console.log(successResult.err());
}
// Simulate an error scenario
const errorResult = fetchData(false);
if (errorResult.is_err()) {
console.log(errorResult.err()); // Output: 'Failed to retrieve data'
} else {
console.log(errorResult.ok());
}
try {
console.log(successResult.unwrap()); // Output: 'Data retrieved successfully'
console.log(errorResult.unwrap()); // Throws error: "Called unwrap() on an Ok value"
} catch (e) {
console.error(e.message);
}
try {
console.log(successResult.unwrap_err()); // Throws error: "Called unwrap_err() on an Ok value"
} catch (e) {
console.error(e.message);
}
- Eliminates Ambiguity: Clear distinction between success and error states.
- Improves Readability: Code is more declarative and self-documenting.
- Avoids Exceptions: Encourages error handling through return types instead of exceptions.
- Enhances Debugging: Easily identify and manage error cases.
A generic class representing either a success (Ok
) or failure (Err
) value.
-
is_ok(): boolean
: Returnstrue
if the result isOk
. -
is_err(): boolean
: Returnstrue
if the result isErr
. -
ok(): A
: Retrieves the success value. -
err(): E
: Retrieves the error value. -
unwrap(): A
: Returns the success value or throws an error if the result isErr
. -
unwrap_err(): E
: Returns the error value or throws an error if the result isOk
.
A subclass of Result
representing a success state.
A subclass of Result
representing an error state.
An interface for creating Ok
and Err
instances.
-
Ok<A, E>(value: A): Ok<A, E>
: Creates anOk
result with the given value. -
Err<E, A>(error: E): Err<E, A>
: Creates anErr
result with the given error.
Contributions are welcome! Please open an issue or submit a pull request for enhancements or bug fixes.
This library is licensed under the MIT License. See LICENSE
for details.