> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cbrock.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Result

> The Result type and its instance methods.

`Result<T, E>` represents a value that is either a success (`Ok<T>`) or a failure (`Err<E>`). Every `Result` carries its error type in the signature; no implicit `throw`, no silent `null`. Both branches share the same set of chainable methods.

```typescript theme={null}
import { chas } from 'ts-chas';

// Ok branch — has .ok === true and .value
const success: chas.Result<number, never> = chas.ok(42);

// Err branch — has .ok === false and .error
const failure: chas.Result<never, string> = chas.err('something went wrong');
```

***

## Creating Results

### `chas.ok(value)`

Wraps a value in an `Ok` result.

<ParamField path="value" type="T" required>
  The success value to wrap.
</ParamField>

<ResponseField name="returns" type="Result<T, never>">
  A result in the `Ok` state containing `value`.
</ResponseField>

```typescript theme={null}
const result = chas.ok(42);
// result.ok === true
// result.value === 42
```

***

### `chas.err(error)`

Wraps an error in an `Err` result.

<ParamField path="error" type="E" required>
  The error value to wrap.
</ParamField>

<ResponseField name="returns" type="Result<never, E>">
  A result in the `Err` state containing `error`.
</ResponseField>

```typescript theme={null}
const result = chas.err('not found');
// result.ok === false
// result.error === 'not found'
```

***

### `chas.okAsync(value)`

Wraps a value (or `Promise` of a value) in a `ResultAsync` that resolves to `Ok`.

<ParamField path="value" type="T | Promise<T>" required>
  The success value or promise to wrap.
</ParamField>

<ResponseField name="returns" type="ResultAsync<T, never>">
  A `ResultAsync` that resolves to `Ok(value)`.
</ResponseField>

```typescript theme={null}
const res = chas.okAsync(42);
const result = await res; // Ok(42)
```

***

### `chas.errAsync(error)`

Wraps an error (or `Promise` of an error) in a `ResultAsync` that resolves to `Err`.

<ParamField path="error" type="E | Promise<E>" required>
  The error value or promise to wrap.
</ParamField>

<ResponseField name="returns" type="ResultAsync<never, E>">
  A `ResultAsync` that resolves to `Err(error)`.
</ResponseField>

```typescript theme={null}
const res = chas.errAsync('request failed');
const result = await res; // Err('request failed')
```

***

### `chas.tryCatch(fn, mapErr?)`

Calls a synchronous function that may throw and wraps the outcome in a `Result`. Returns `Ok` on success or `Err` if the function throws.

<ParamField path="fn" type="() => T" required>
  The synchronous function to call.
</ParamField>

<ParamField path="mapErr" type="(error: unknown) => E">
  Maps the thrown value to your error type. When omitted, the error is typed as `unknown`.
</ParamField>

<ResponseField name="returns" type="Result<T, E>">
  `Ok(returnValue)` or `Err(mappedError)`.
</ResponseField>

```typescript theme={null}
const result = chas.tryCatch(
  () => JSON.parse('{"name":"Alice"}'),
  (e) => new Error(`Invalid JSON: ${e}`)
);

if (result.isOk()) {
  console.log(result.value.name); // 'Alice'
}
```

***

### `chas.fromPromise(promise, mapErr?)`

Wraps a `Promise` in a `ResultAsync`. Resolves to `Ok` on fulfillment or `Err` on rejection.

<ParamField path="promise" type="Promise<T>" required>
  The promise to wrap.
</ParamField>

<ParamField path="mapErr" type="(error: unknown) => E">
  Maps the rejection reason to your error type. When omitted, the error is typed as `unknown`.
</ParamField>

<ResponseField name="returns" type="ResultAsync<T, E>">
  A `ResultAsync` wrapping the promise outcome.
</ResponseField>

```typescript theme={null}
const result = await chas.fromPromise(
  fetch('/api/user').then(r => r.json()),
  (e) => `Fetch failed: ${e}`
);

if (result.isOk()) {
  console.log(result.value); // parsed JSON body
}
```

***

## Instance methods

Every `Result<T, E>` has the following methods regardless of whether it is `Ok` or `Err`.

### `.isOk()`

Type guard that narrows to `Ok<T>`.

<ResponseField name="returns" type="boolean">
  `true` if the result is `Ok<T>`, `false` otherwise. When `true`, TypeScript narrows the type so `result.value` is accessible.
</ResponseField>

```typescript theme={null}
const result = chas.ok(5);

if (result.isOk()) {
  console.log(result.value); // 5 — TypeScript knows .value exists here
}
```

***

### `.isErr()`

Type guard that narrows to `Err<E>`.

<ResponseField name="returns" type="boolean">
  `true` if the result is `Err<E>`, `false` otherwise. When `true`, TypeScript narrows the type so `result.error` is accessible.
</ResponseField>

```typescript theme={null}
const result = chas.err('not found');

if (result.isErr()) {
  console.log(result.error); // 'not found'
}
```

***

### `.map(fn)`

Transforms the `Ok` value. `Err` passes through unchanged.

<ParamField path="fn" type="(value: T) => U" required>
  Function applied to the `Ok` value.
</ParamField>

<ResponseField name="returns" type="Result<U, E>">
  `Ok(fn(value))` or the original `Err`.
</ResponseField>

```typescript theme={null}
const doubled = chas.ok(5).map(v => v * 2);
// Ok(10)

const passthrough = chas.err('oops').map(v => v * 2);
// Err('oops') — fn is never called
```

***

### `.mapErr(fn)`

Transforms the `Err` error. `Ok` passes through unchanged.

<ParamField path="fn" type="(error: E) => F" required>
  Function applied to the `Err` error.
</ParamField>

<ResponseField name="returns" type="Result<T, F>">
  The original `Ok` or `Err(fn(error))`.
</ResponseField>

```typescript theme={null}
const result = chas.err('not_found').mapErr(e => e.toUpperCase());
// Err('NOT_FOUND')
```

***

### `.andThen(fn)`

Chains another `Result`-returning function (flatMap / monadic bind). If `Ok`, calls `fn` with the value and returns its result. `Err` short-circuits.

<ParamField path="fn" type="(value: T) => Result<U, F>" required>
  Function that receives the `Ok` value and returns a new `Result`.
</ParamField>

<ResponseField name="returns" type="Result<U, E | F>">
  The result of `fn`, or the original `Err`.
</ResponseField>

```typescript theme={null}
function parseAge(raw: string): chas.Result<number, string> {
  const n = parseInt(raw, 10);
  return isNaN(n) ? chas.err('not a number') : chas.ok(n);
}

function validateAge(age: number): chas.Result<number, string> {
  return age >= 18 ? chas.ok(age) : chas.err('too young');
}

const result = parseAge('21').andThen(validateAge);
// Ok(21)

const failed = parseAge('abc').andThen(validateAge);
// Err('not a number') — validateAge is never called
```

***

### `.orElse(fn)`

Recovers from an `Err` by calling `fn` with the error and returning its result. `Ok` passes through unchanged.

<ParamField path="fn" type="(error: E) => Result<T2, F>" required>
  Function that receives the `Err` error and returns a recovery `Result`.
</ParamField>

<ResponseField name="returns" type="Result<T | T2, F>">
  The original `Ok`, or the result of `fn`.
</ResponseField>

```typescript theme={null}
const result = chas.err('cache miss')
  .orElse(() => chas.ok('default value'));
// Ok('default value')
```

***

### `.tap(fn)`

Runs a side effect when `Ok`. Returns the original result unchanged.

<ParamField path="fn" type="(value: T) => void" required>
  Side-effect function called with the `Ok` value.
</ParamField>

<ResponseField name="returns" type="Result<T, E>">
  The original result, unmodified.
</ResponseField>

```typescript theme={null}
const result = chas.ok(42)
  .tap(v => console.log('Got value:', v)) // logs 42
  .map(v => v * 2);
// Ok(84) — tap did not alter the value
```

***

### `.tapErr(fn)`

Runs a side effect when `Err`. Returns the original result unchanged.

<ParamField path="fn" type="(error: E) => void" required>
  Side-effect function called with the `Err` error.
</ParamField>

<ResponseField name="returns" type="Result<T, E>">
  The original result, unmodified.
</ResponseField>

```typescript theme={null}
chas.err('upload failed')
  .tapErr(e => console.error('Error:', e))
  .mapErr(e => ({ message: e }));
```

***

### `.match({ ok, err })`

Exhaustively handles both branches and returns a value. Unlike `.map`, this always produces a non-`Result` value.

<ParamField path="ok" type="(value: T) => U" required>
  Handler called when the result is `Ok`.
</ParamField>

<ParamField path="err" type="(error: E) => F" required>
  Handler called when the result is `Err`.
</ParamField>

<ResponseField name="returns" type="U | F">
  The return value of whichever handler ran.
</ResponseField>

```typescript theme={null}
const message = chas.ok(42).match({
  ok: v => `The answer is ${v}`,
  err: e => `Failed: ${e}`,
});
// 'The answer is 42'
```

***

### `.unwrap()`

Returns the `Ok` value, or throws the `Err` error.

<ResponseField name="returns" type="T">
  The `Ok` value.
</ResponseField>

<Warning>
  Throws the contained error if the result is `Err`. Prefer `.unwrapOr()`, `.match()`, or type-guarded access in production code.
</Warning>

```typescript theme={null}
const value = chas.ok(5).unwrap(); // 5
chas.err('oops').unwrap();          // throws 'oops'
```

***

### `.unwrapOr(defaultValue)`

Returns the `Ok` value, or `defaultValue` if `Err`.

<ParamField path="defaultValue" type="T2" required>
  Fallback value returned when the result is `Err`.
</ParamField>

<ResponseField name="returns" type="T | T2">
  The `Ok` value or the default.
</ResponseField>

```typescript theme={null}
const value = chas.err('missing').unwrapOr(0);
// 0
```

***

### `.unwrapErr()`

Returns the `Err` error, or throws if `Ok`.

<ResponseField name="returns" type="E">
  The `Err` error.
</ResponseField>

```typescript theme={null}
const error = chas.err('not found').unwrapErr();
// 'not found'
```

***

### `.toOption()`

Discards the error and converts to an `Option<T>`. `Ok` becomes `Some`, `Err` becomes `None`.

<ResponseField name="returns" type="Option<T>">
  `Some(value)` when `Ok`, or `None` when `Err`.
</ResponseField>

```typescript theme={null}
const some = chas.ok(42).toOption();  // Some(42)
const none = chas.err('x').toOption(); // None
```

***

### `.pipe(fn1, fn2, ...)`

Passes the result through a sequence of functions. Each function receives the output of the previous one. Up to 9 functions are supported with full type inference.

<ParamField path="fn1, fn2, ..." type="(a: A) => B" required>
  Functions to apply in order.
</ParamField>

<ResponseField name="returns" type="B">
  The output of the last function.
</ResponseField>

```typescript theme={null}
const add5 = (r: chas.Result<number, never>) => r.map(v => v + 5);
const double = (r: chas.Result<number, never>) => r.map(v => v * 2);

const result = chas.ok(1).pipe(add5, double);
// Ok(12)
```

***

### `.context(ctx)`

Attaches a debug label or metadata object to the error when `Err`. Context entries are stored in `error._context` as an array, most recent first. No-op when `Ok`.

<ParamField path="ctx" type="string | Record<string, unknown>" required>
  A description string or metadata object for the current step.
</ParamField>

<ResponseField name="returns" type="Result<T, E>">
  The same result with context prepended to `error._context` (if `Err`).
</ResponseField>

```typescript theme={null}
const result = await fetchUser(id)
  .context('fetching user')
  .andThen(u => validatePermissions(u))
  .context('checking permissions');

if (result.isErr()) {
  console.log(result.error._context);
  // ['checking permissions', 'fetching user']
}
```

***

### `.catchTag(target, handler)`

Catches a specific tagged error variant by its `_tag` string or error factory, calls `handler` with it, and removes that tag from the error union type. Unmatched tags pass through unchanged.

<ParamField path="target" type="string | ErrorFactory" required>
  The `_tag` string to match, or an error factory created with `chas.defineErrs`.
</ParamField>

<ParamField path="handler" type="(error: MatchedError) => Result<T2, E2>" required>
  Recovery function. Return a new `Result` to replace the caught error.
</ParamField>

<ResponseField name="returns" type="Result<T | T2, Exclude<E, { _tag: ... }> | E2>">
  A result with the matched tag removed from the error union.
</ResponseField>

```typescript theme={null}
const AppError = chas.defineErrs({
  NotFound: (resource: string) => ({ resource }),
  Unauthorized: () => ({}),
});

// fetchUser returns Result<User, NotFound | Unauthorized>
const result = getUser(id)
  .catchTag('NotFound', () => chas.ok(GUEST_USER));
// Result<User | GuestUser, Unauthorized> — NotFound is removed from the union
```

***

### `.tapTag(target, handler)`

Runs a side effect for a specific tagged error, leaving the result unchanged. Use this for logging or telemetry on individual error variants.

<ParamField path="target" type="string | ErrorFactory" required>
  The `_tag` string to match, or an error factory.
</ParamField>

<ParamField path="handler" type="(error: MatchedError) => void" required>
  Side-effect function called when the tag matches.
</ParamField>

<ResponseField name="returns" type="Result<T, E>">
  The original result, unmodified.
</ResponseField>

```typescript theme={null}
getUser(id)
  .tapTag('NotFound', (e) => analytics.track('user_not_found', { id }))
  .tapTag('Unauthorized', () => redirectToLogin());
```
