---
url: /unthrown/api/orpc/client.md
---
[**@unthrown/orpc**](index.md)

***

[@unthrown/orpc](index.md) / client

# client

## Client

### CreateResultClientOptions

```ts
type CreateResultClientOptions = object;
```

Defined in: [client.ts:130](https://github.com/btravstack/unthrown/blob/f4578e4b398ad7f3913ba2dec0343621762bbb27/packages/orpc/src/client.ts#L130)

Options of [createResultClient](#createresultclient).

#### Properties

| Property | Type | Description | Defined in |
| ------ | ------ | ------ | ------ |
|  `contract?` | `RouterContract` | The contract the client was built from. When given, every rejected call is reconciled against the procedure's own `.errors({...})` entry before triage: an `Err` is then a code the client declares, with `data` that passed its schema, whatever `defined` flag the server sent. Recommended whenever the server is not fully trusted: without it, the server's `defined` flag decides and `error.data` reaches `E` **unvalidated** — typed as the declared schema's output, but never checked against it. | [client.ts:141](https://github.com/btravstack/unthrown/blob/f4578e4b398ad7f3913ba2dec0343621762bbb27/packages/orpc/src/client.ts#L141) |

***

### ResultClient

```ts
type ResultClient<T> = T extends Client<infer UContext, infer UInput, infer UOutput, infer UError> ? (...rest) => AsyncResult<UOutput, Extract<UError, AnyORPCError>> : { [K in keyof T]: T[K] extends AnyNestedClient ? ResultClient<T[K]> : never };
```

Defined in: [client.ts:120](https://github.com/btravstack/unthrown/blob/f4578e4b398ad7f3913ba2dec0343621762bbb27/packages/orpc/src/client.ts#L120)

The type of a [createResultClient](#createresultclient) client: every procedure of `T`
returns an `AsyncResult` instead of a throwing promise.

#### Type Parameters

| Type Parameter |
| ------ |
| `T` *extends* `AnyNestedClient` |

***

### createResultClient()

```ts
function createResultClient<T>(client, options?): ResultClient<T>;
```

Defined in: [client.ts:190](https://github.com/btravstack/unthrown/blob/f4578e4b398ad7f3913ba2dec0343621762bbb27/packages/orpc/src/client.ts#L190)

Wrap an oRPC client so every procedure call returns an
`AsyncResult` — [fromCall](#fromcall) applied to the whole router.

#### Type Parameters

| Type Parameter |
| ------ |
| `T` *extends* `AnyNestedClient` |

#### Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `client` | `T` | the oRPC client (or any nested router segment) to wrap. |
| `options` | [`CreateResultClientOptions`](#createresultclientoptions) | see [CreateResultClientOptions](#createresultclientoptions). |

#### Returns

[`ResultClient`](#resultclient)<`T`>

#### Remarks

The mirror of oRPC's own `createSafeClient`, producing `AsyncResult`s
instead of `SafeResult` tuples: defined errors land in the error channel
(the raw `ORPCError` union, discriminated by `code`), everything else is a
`Defect`. Call options (`signal`, `context`, `lastEventId`) pass through
untouched.

Pass the client's `contract` whenever the server is not fully trusted or
deploys independently: the error channel is then decided by the contract
the caller compiled against, not by the server's, and `error.data` is
validated against its schema (see [CreateResultClientOptions.contract](#contract)).
Without it, `data` is trusted as sent.

Event-iterator (streaming) procedures are out of scope: a stream does not
collapse to one `Result`. Keep calling those on the raw client.

#### Example

```ts
import { createResultClient } from "@unthrown/orpc/client";

const rc = createResultClient(client, { contract });

const greeting = await rc.planet
  .find({ id })
  .map((planet) => `Hello, ${planet.name}!`)
  .match({
    ok: (msg) => msg,
    // the `errCases` handler matches the error exhaustively: one arm per
    // `code` the procedure declares — no catch-all to absorb a new one
    errCases: (matcher) =>
      matcher
        .with({ code: "NOT_FOUND" }, () => "Hello, void!")
        .with({ code: "CONFLICT" }, () => "Hello, again!"),
    defect: () => "Hello, bug tracker!",
  });
```

***

### fromCall()

```ts
function fromCall<TOutput, TError>(promise): AsyncResult<TOutput, Extract<TError, AnyORPCError>>;
```

Defined in: [client.ts:86](https://github.com/btravstack/unthrown/blob/f4578e4b398ad7f3913ba2dec0343621762bbb27/packages/orpc/src/client.ts#L86)

Lift a single oRPC call into an `AsyncResult`.

#### Type Parameters

| Type Parameter | Default type | Description |
| ------ | ------ | ------ |
| `TOutput` | - | the procedure's output type. |
| `TError` | `Error` | the call's error union; only its `ORPCError` arm is modeled, the rest is subtracted into the defect channel. |

#### Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `promise` | `PromiseWithError`<`TOutput`, `TError`> | the in-flight call to lift. |

#### Returns

`AsyncResult`<`TOutput`, `Extract`<`TError`, `AnyORPCError`>>

#### Remarks

The error channel is the call's *defined* errors — the `ORPCError`s whose
`code` the procedure declares via `.errors({...})`, extracted as
`Extract<TError, AnyORPCError>` and discriminated by `code`. Any other
rejection (network failure, an undeclared `ORPCError`, an opaque throw
collapsed to `INTERNAL_SERVER_ERROR`, a malformed response) is a `Defect`:
unmodeled, flowing past the error combinators, panicking at `get`.

Accepts the promise of a client procedure call or of oRPC's server-side
`call(procedure, input)` — anything typed `PromiseWithError`.

`fromCall` has no contract to check against: the `defined` flag the server
sent decides the channel, and `error.data` is trusted, **not validated**.
Against a server you do not fully trust, prefer
[createResultClient](#createresultclient) with its `contract` option.

#### Example

```ts
import { fromCall } from "@unthrown/orpc/client";

const planet = await fromCall(client.planet.find({ id }));
// planet: Result<Planet, ORPCError<"NOT_FOUND", undefined>>
if (planet.isErr()) planet.error.code; // "NOT_FOUND"
```
