errore 0.2.0 → 0.3.0

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 +91 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -201,6 +201,96 @@ This works because:
201
201
  2. Custom error classes extend `Error`
202
202
  3. After an `instanceof Error` check, TS excludes all Error subtypes
203
203
 
204
+ ## Result + Option Combined: `Error | T | null`
205
+
206
+ One of errore's best features: you can naturally combine error handling with optional values. No wrapper nesting needed!
207
+
208
+ In Rust, you'd need `Result<Option<T>, E>` or `Option<Result<T, E>>` and worry about the order. Here it's just a union:
209
+
210
+ ```ts
211
+ // Result + Option in one natural type
212
+ function findUser(id: string): NotFoundError | User | null {
213
+ if (id === 'bad') return new NotFoundError({ id })
214
+ if (id === 'missing') return null
215
+ return { id, name: 'Alice' }
216
+ }
217
+
218
+ const user = findUser('123')
219
+
220
+ // Handle error first
221
+ if (isError(user)) {
222
+ return user.message // TypeScript: user is NotFoundError
223
+ }
224
+
225
+ // Handle null/missing case - use ?. and ?? naturally!
226
+ const name = user?.name ?? 'Anonymous'
227
+
228
+ // Or check explicitly
229
+ if (user === null) {
230
+ return 'User not found'
231
+ }
232
+
233
+ // TypeScript knows: user is User
234
+ console.log(user.name)
235
+ ```
236
+
237
+ ### Works with `undefined` too
238
+
239
+ ```ts
240
+ function lookup(key: string): NetworkError | string | undefined {
241
+ if (key === 'fail') return new NetworkError({ url: '/api', message: 'Failed' })
242
+ if (key === 'missing') return undefined
243
+ return 'found-value'
244
+ }
245
+
246
+ const value = lookup('key')
247
+
248
+ if (isError(value)) return value
249
+
250
+ // ?? works naturally with undefined
251
+ const result = value ?? 'default'
252
+ ```
253
+
254
+ ### Triple union: `Error | T | null | undefined`
255
+
256
+ Even this works with full type inference:
257
+
258
+ ```ts
259
+ function query(sql: string): ValidationError | { rows: string[] } | null | undefined {
260
+ if (sql === 'invalid') return new ValidationError({ field: 'sql', message: 'Bad' })
261
+ if (sql === 'empty') return null // explicitly no data
262
+ if (sql === 'no-table') return undefined // table doesn't exist
263
+ return { rows: ['a', 'b'] }
264
+ }
265
+
266
+ const result = query('SELECT *')
267
+
268
+ if (isError(result)) {
269
+ return result.field // TypeScript: ValidationError
270
+ }
271
+
272
+ if (result == null) {
273
+ return 'no data' // handles both null and undefined
274
+ }
275
+
276
+ // TypeScript: { rows: string[] }
277
+ console.log(result.rows)
278
+ ```
279
+
280
+ ### Why this is better than Rust/Zig
281
+
282
+ | Language | Result + Option | Order matters? |
283
+ |----------|-----------------|----------------|
284
+ | Rust | `Result<Option<T>, E>` or `Option<Result<T, E>>` | Yes, must unwrap in order |
285
+ | Zig | `!?T` (error union + optional) | Yes, specific syntax |
286
+ | **errore** | `Error \| T \| null` | **No!** Check in any order |
287
+
288
+ With errore:
289
+ - Use `?.` and `??` naturally
290
+ - Check `isError()` or `=== null` in any order
291
+ - No unwrapping ceremony
292
+ - TypeScript infers everything
293
+
204
294
  ## Comparison with Result Types
205
295
 
206
296
  | Result Pattern | errore |
@@ -210,6 +300,7 @@ This works because:
210
300
  | `result.value` | direct access after guard |
211
301
  | `result.map(fn)` | `map(result, fn)` |
212
302
  | `Result<User, Error>` | `Error \| User` |
303
+ | `Result<Option<T>, E>` | `Error \| T \| null` |
213
304
 
214
305
  ## License
215
306
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "errore",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Type-safe errors as values for TypeScript. Like Go, but with full type inference.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",