# Function: fn()

Wraps a function that may throw and returns a new function that returns a [Result](../types/Result.Result.md) or [ResultAsync](../types/Result.ResultAsync.md).

You can use either a custom `catch` handler or rely on the `safe: true` option
to assume the function cannot throw.

## Type Param

**T**

The function type to execute (sync or async) or a Promise type.

## Type Param

**E**

The error type to return if `catch` is used.

## Examples

**Sync try-catch**

```ts
import { Result } from '@praha/byethrow';

const fn = Result.fn({
  try: (x: number) => {
    if (x < 0) throw new Error('Negative!');
    return x * 2;
  },
  catch: (error) => new Error('Oops!', { cause: error }),
});

const result = fn(5); // Result.Result<number, Error>
```

**Sync safe**

```ts
import { Result } from '@praha/byethrow';

const fn = Result.fn({
  safe: true,
  try: (x: number) => x + 1,
});

const result = fn(1); // Result.Result<number, never>
```

**Async try-catch**

```ts
import { Result } from '@praha/byethrow';

const fn = Result.fn({
  try: async (id: string) => await fetch(`/api/data/${id}`),
  catch: (error) => new Error('Oops!', { cause: error }),
});

const result = await fn('abc'); // Result.ResultAsync<Response, Error>
```

**Async safe**

```ts
import { Result } from '@praha/byethrow';

const fn = Result.fn({
  safe: true,
  try: async () => await Promise.resolve('ok'),
});

const result = await fn(); // Result.ResultAsync<string, never>
```

## Call Signature

> **fn**\<`T`, `E`>(`options`): (...`args`) => [`ResultAsync`](../types/Result.ResultAsync.md)\<`Awaited`\<`ReturnType`\<`T`>>, `E`>

### Type Parameters

#### T

`T` _extends_ (...`args`) => `Promise`\<`any`>

#### E

`E`

### Parameters

#### options

##### catch

(`error`) => `E`

##### try

`T`

### Returns

(...`args`) => [`ResultAsync`](../types/Result.ResultAsync.md)\<`Awaited`\<`ReturnType`\<`T`>>, `E`>

## Call Signature

> **fn**\<`T`>(`options`): (...`args`) => [`ResultAsync`](../types/Result.ResultAsync.md)\<`Awaited`\<`ReturnType`\<`T`>>, `never`>

### Type Parameters

#### T

`T` _extends_ (...`args`) => `Promise`\<`any`>

### Parameters

#### options

##### safe

`true`

##### try

`T`

### Returns

(...`args`) => [`ResultAsync`](../types/Result.ResultAsync.md)\<`Awaited`\<`ReturnType`\<`T`>>, `never`>

## Call Signature

> **fn**\<`T`, `E`>(`options`): (...`args`) => [`Result`](../types/Result.Result.md)\<`ReturnType`\<`T`>, `E`>

### Type Parameters

#### T

`T` _extends_ (...`args`) => `any`

#### E

`E`

### Parameters

#### options

##### catch

(`error`) => `E`

##### try

`T`

### Returns

(...`args`) => [`Result`](../types/Result.Result.md)\<`ReturnType`\<`T`>, `E`>

## Call Signature

> **fn**\<`T`>(`options`): (...`args`) => [`Result`](../types/Result.Result.md)\<`ReturnType`\<`T`>, `never`>

### Type Parameters

#### T

`T` _extends_ (...`args`) => `any`

### Parameters

#### options

##### safe

`true`

##### try

`T`

### Returns

(...`args`) => [`Result`](../types/Result.Result.md)\<`ReturnType`\<`T`>, `never`>
