https://github.com/michaelpiper/result-library
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.
https://github.com/michaelpiper/result-library
Last synced: over 1 year ago
JSON representation
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.
- Host: GitHub
- URL: https://github.com/michaelpiper/result-library
- Owner: michaelpiper
- License: mit
- Created: 2025-01-16T13:59:35.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-07T09:34:22.000Z (over 1 year ago)
- Last Synced: 2025-03-07T10:09:30.652Z (over 1 year ago)
- Language: TypeScript
- Size: 17.6 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Result Library
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.
## Features
- **Type Safety**: Explicitly handle `Ok` and `Err` 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.
## Installation
```bash
npm install result-library
```
## Usage
### Creating Results
To create `Ok` and `Err` results, use the `ResultBuilder` interface.
```typescript
import { ResultBuilder } from 'result-library';
const { Ok, Err } = ResultBuilder();
const success = Ok("Operation was successful");
const failure = Err("An error occurred");
```
### Checking Results
```typescript
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());
}
```
### Example Use Case
```typescript
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());
}
```
### Advanced Usage with Types
You can define explicit types for better type safety.
```typescript
const { Ok, Err } = ResultBuilder();
const result = Ok(42);
const error = Err("Something went wrong");
if (result.is_ok()) {
console.log(result.unwrap());
} else {
console.error(result.unwrap_err());
}
```
### Additional Example: Handling Multiple Cases
```typescript
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());
}
```
### Use Case: File Processing
```typescript
function processFile(filePath: string) {
const { Ok, Err } = ResultBuilder();
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());
}
```
### Use Case: API Response Handling
```typescript
async function fetchData(apiUrl: string) {
const { Ok, Err } = ResultBuilder();
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.
### Code Example:
```typescript
import { ResultBuilder } from 'result-library';
// deconstruct ResultBuilder and create Ok, Err builder instance
const { Ok, Err } = ResultBuilder();
// 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);
}
```
## Advantages
1. **Eliminates Ambiguity**: Clear distinction between success and error states.
2. **Improves Readability**: Code is more declarative and self-documenting.
3. **Avoids Exceptions**: Encourages error handling through return types instead of exceptions.
4. **Enhances Debugging**: Easily identify and manage error cases.
## API Reference
### `Result`
A generic class representing either a success (`Ok`) or failure (`Err`) value.
#### Methods:
- **`is_ok(): boolean`**: Returns `true` if the result is `Ok`.
- **`is_err(): boolean`**: Returns `true` if the result is `Err`.
- **`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 is `Err`.
- **`unwrap_err(): E`**: Returns the error value or throws an error if the result is `Ok`.
### `Ok`
A subclass of `Result` representing a success state.
### `Err`
A subclass of `Result` representing an error state.
### `ResultBuilder`
An interface for creating `Ok` and `Err` instances.
- **`Ok(value: A): Ok`**: Creates an `Ok` result with the given value.
- **`Err(error: E): Err`**: Creates an `Err` result with the given error.
## Contributing
Contributions are welcome! Please open an issue or submit a pull request for enhancements or bug fixes.
## License
This library is licensed under the MIT License. See `LICENSE` for details.