@mkvlrn/result 5.0.6 → 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.
- package/README.md +35 -28
- package/package.json +6 -9
package/README.md
CHANGED
|
@@ -1,47 +1,45 @@
|
|
|
1
1
|
# @mkvlrn/result
|
|
2
2
|
|
|
3
|
-
|
|
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
|
[](https://www.npmjs.com/package/@mkvlrn/result)
|
|
6
8
|
|
|
7
|
-
##
|
|
9
|
+
## Why this one?
|
|
8
10
|
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16
|
-
import { Result, AsyncResult, ok, err } from "@mkvlrn/result";
|
|
15
|
+
**The entire implementation is ~35 lines. Zero runtime dependencies. Four exports.**
|
|
17
16
|
|
|
18
|
-
|
|
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
|
-
|
|
22
|
-
const failure = err(new Error("Something went wrong"));
|
|
19
|
+
## Installation
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
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 |
|
|
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
|
-
|
|
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
|
-
###
|
|
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); //
|
|
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
|
|
87
|
+
readonly code: number;
|
|
82
88
|
|
|
83
|
-
constructor(
|
|
89
|
+
constructor(code: number, message: string) {
|
|
84
90
|
super(message);
|
|
85
91
|
this.name = "ValidationError";
|
|
86
|
-
this.
|
|
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, "
|
|
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
|
-
|
|
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.
|
|
4
|
+
"version": "5.0.8",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"author": "Mike Valeriano <mkvlrn@gmail.com>",
|
|
@@ -14,25 +14,22 @@
|
|
|
14
14
|
"typescript",
|
|
15
15
|
"result"
|
|
16
16
|
],
|
|
17
|
-
"engines": {
|
|
18
|
-
"node": "24"
|
|
19
|
-
},
|
|
20
17
|
"files": [
|
|
21
18
|
"build"
|
|
22
19
|
],
|
|
23
20
|
"imports": {
|
|
24
|
-
"
|
|
21
|
+
"#/*": "./src/*.ts"
|
|
25
22
|
},
|
|
26
23
|
"exports": {
|
|
27
24
|
"types": "./build/index.d.ts",
|
|
28
25
|
"default": "./build/index.js"
|
|
29
26
|
},
|
|
30
27
|
"devDependencies": {
|
|
31
|
-
"@types/node": "^25.
|
|
32
|
-
"lint-staged": "^16.2
|
|
28
|
+
"@types/node": "^25.3.3",
|
|
29
|
+
"lint-staged": "^16.3.2",
|
|
33
30
|
"tsc-files": "^1.1.4",
|
|
34
|
-
"tsdown": "0.20.
|
|
35
|
-
"typescript": "
|
|
31
|
+
"tsdown": "0.20.3",
|
|
32
|
+
"typescript": "6.0.0-beta",
|
|
36
33
|
"vitest": "^4.0.18"
|
|
37
34
|
},
|
|
38
35
|
"scripts": {
|