@mkvlrn/result 5.0.7 → 5.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +35 -28
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,47 +1,45 @@
1
1
  # @mkvlrn/result
2
2
 
3
- Type-safe Result pattern for TypeScript representing success or error. Anything to avoid try/catch hell.
3
+ Dead simple Result pattern for TypeScript.
4
+
5
+ No `.map()`, no `.flatMap()`, no `.andThen()`, no `.orElse()`, no `.unwrap()`, no monadic gymnastics. Just a type, two functions, and TypeScript doing what TypeScript already does well.
4
6
 
5
7
  [![npm](https://img.shields.io/npm/v/@mkvlrn/result)](https://www.npmjs.com/package/@mkvlrn/result)
6
8
 
7
- ## Installation
9
+ ## Why this one?
8
10
 
9
- ```bash
10
- pnpm add @mkvlrn/result
11
- ```
11
+ There are dozens of Result libraries for TypeScript. Nearly all of them bolt on method chaining, transformation pipelines, and functional programming utilities that turn a simple concept into an entire paradigm.
12
12
 
13
- ## Usage
13
+ This package does **one thing**: gives you a type-safe `Result<T, E>` discriminated union with `ok()` and `err()` constructors. You use `if/else` to handle it. TypeScript narrows the type for you. That's the whole API.
14
14
 
15
- ```typescript
16
- import { Result, AsyncResult, ok, err } from "@mkvlrn/result";
15
+ **The entire implementation is ~35 lines. Zero runtime dependencies. Four exports.**
17
16
 
18
- // Success
19
- const success = ok(42);
17
+ If you need `.map().flatMap().andThen().orElse().unwrapOr()` chains, use [neverthrow](https://github.com/supermacro/neverthrow) or [ts-results](https://github.com/vultix/ts-results). They're good libraries. This isn't that.
20
18
 
21
- // Error
22
- const failure = err(new Error("Something went wrong"));
19
+ ## Installation
23
20
 
24
- // Check result
25
- const result = ok(42);
26
- if (result.isError) {
27
- console.log("Error:", result.error.message);
28
- } else {
29
- console.log("Value:", result.value);
30
- }
21
+ ```bash
22
+ pnpm add @mkvlrn/result
31
23
  ```
32
24
 
33
25
  ## API
34
26
 
35
- | Export | Description |
27
+ | Export | What it does |
36
28
  | ------------------- | -------------------------------------------- |
37
29
  | `Result<T, E>` | Union type representing success or failure |
38
30
  | `AsyncResult<T, E>` | `Promise<Result<T, E>>` for async operations |
39
31
  | `ok(value)` | Creates a success result |
40
32
  | `err(error)` | Creates an error result |
41
33
 
42
- ## Examples
34
+ That's it. That's the whole thing.
35
+
36
+ ## Usage
37
+
38
+ ```typescript
39
+ import { type Result, type AsyncResult, ok, err } from "@mkvlrn/result";
40
+ ```
43
41
 
44
- ### Basic Function
42
+ ### Create results, check results
45
43
 
46
44
  ```typescript
47
45
  function divide(a: number, b: number): Result<number, Error> {
@@ -53,10 +51,16 @@ function divide(a: number, b: number): Result<number, Error> {
53
51
 
54
52
  const result = divide(10, 2);
55
53
  if (result.isOk) {
56
- console.log(result.value); // 5
54
+ console.log(result.value); // number - TypeScript knows
55
+ }
56
+
57
+ if (result.isError) {
58
+ console.log(result.error.message); // Error - TypeScript knows
57
59
  }
58
60
  ```
59
61
 
62
+ No `.unwrap()`. No `.expect()`. Just an `if` statement and the compiler handles the rest.
63
+
60
64
  ### Async Operations
61
65
 
62
66
  ```typescript
@@ -74,29 +78,32 @@ async function fetchUser(id: number): AsyncResult<User, Error> {
74
78
  }
75
79
  ```
76
80
 
81
+ `AsyncResult<T, E>` is just `Promise<Result<T, E>>`. It's a type alias, not a class, not a wrapper, not a monad.
82
+
77
83
  ### Custom Error Types
78
84
 
79
85
  ```typescript
80
86
  class ValidationError extends Error {
81
- readonly customField: number;
87
+ readonly code: number;
82
88
 
83
- constructor(customField: number, message: string) {
89
+ constructor(code: number, message: string) {
84
90
  super(message);
85
91
  this.name = "ValidationError";
86
- this.customField = customField;
92
+ this.code = code;
87
93
  }
88
94
  }
89
95
 
90
96
  function validateEmail(email: string): Result<string, ValidationError> {
91
97
  if (!email.includes("@")) {
92
- return err(new ValidationError(400, "custom"));
98
+ return err(new ValidationError(400, "bad-email"));
93
99
  }
94
100
  return ok(email);
95
101
  }
96
102
 
97
103
  const result = validateEmail("invalid-email");
98
104
  if (result.isError) {
99
- console.log(`${result.error.customField}: ${result.error.message}`);
105
+ // TypeScript knows this is a ValidationError, not just Error
106
+ console.log(`${result.error.code}: ${result.error.message}`); // 400: bad-email
100
107
  }
101
108
  ```
102
109
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mkvlrn/result",
3
3
  "description": "Simple Result type/pattern for TypeScript",
4
- "version": "5.0.7",
4
+ "version": "5.0.8",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "author": "Mike Valeriano <mkvlrn@gmail.com>",
@@ -25,8 +25,8 @@
25
25
  "default": "./build/index.js"
26
26
  },
27
27
  "devDependencies": {
28
- "@types/node": "^25.2.3",
29
- "lint-staged": "^16.2.7",
28
+ "@types/node": "^25.3.3",
29
+ "lint-staged": "^16.3.2",
30
30
  "tsc-files": "^1.1.4",
31
31
  "tsdown": "0.20.3",
32
32
  "typescript": "6.0.0-beta",