Expand description
Type Aliases§
Source§type Result<T, E> = Ok<T> | Err<E>
type Result<T, E> = Ok<T> | Err<E>
A value that either a success (Ok) or an error (Err)
Construct a success with { val: ... } and an error with { err: ... }
Functions§
Source§errstr(e: unknown, recursing?: boolean): string
errstr(e: unknown, recursing?: boolean): string
Try best effort converting an error to a string
Rust-like
Result<T, E>type and error handling utilsI once had a fancy error object with TypeScript magic that tries to reduce allocation while maintaining Result-safety. It turns out that was slower than allocating plain objects for every return, because of how V8 optimizes things.
Don't even use
isErr()helper functions to abstract. They are slower than directly property access in my testing.Function that can fail
Instead of having functions
throw, make itreturninstead.This is similar to Rust:
Calling function that can fail
The recommended pattern is
If your
Etype covers falsy values that are valid, use"err" in xinstead ofx.err. A well-known case isResult<T, unknown>.if(r.err)cannot narrow the else case toOk, butif("err" in r)can.A full example:
Interop with throwing functions
This library also has
tryCatchto interop with throwing functions, andtryAsyncfor async functions.Returning void
Use
Void<E>as the return type if the function returnsvoidon successWhy is there no
match/map/mapErr, etc?If you are thinking this is a great idea:
The vanilla
ifdoesn't allocate the closures, and has less code, and you can control the flow properly inside the blocks withreturn/break/continueAs for the other utility functions from Rust's Result type, they really only benefit because you can early return with
?AND those abstractions are zero-cost in Rust. Neither is true in JavaScript.You can also easily write them yourself if you really want to.