# wrap

`wrap` can secure your functions. This means even if your functions throw errors, it will still be safe to call them without worrying that they will cause your program to crash.

A simple example of wrapping a synchronous function

```typescript
import { wrap } from 'unwrapit'

const tryParseJson = wrap(() => JSON.parse(`{"package": "unwrapit!"}`))
const json = tryParseJson()
if (!json.ok) {
    return json.error
}
console.log(json.value)
```

If you are sure that the wrapped function won't panic anyway, or just for debug usage, you can call `unwrap` method to force unwrap the value.

```typescript
tryParseJson().unwrap()
```

This will unwrap the value without checking whether it will throw an error or not.

You can wrap an asynchronous function as well.

```typescript
import {wrap} from 'unwrapit'

const fetchWrapper = wrap(fetch)
const ret = (await fetchWrapper('www.google.com')).unwrap()
const text = await ret.text()
```

{% hint style="info" %}
Note that you need to `await` or call `then` to resolve the Promise result first because we don't know if the function will throw errors or not without executing it.
{% endhint %}

### Type <a href="#asynchronous-function" id="asynchronous-function"></a>

`wrap` will infer the given function type and return it as is except wrapping the return type of the given function into `Result`.

<pre class="language-typescript"><code class="lang-typescript">declare function fn(a: number): string

const f = wrap(fn)
<strong>//    ^? const f: (a: number) => Result&#x3C;string, unknown>
</strong></code></pre>

For asynchronous functions, the return type looks like below

<pre class="language-typescript"><code class="lang-typescript">declare function fn(a: number): Promise&#x3C;string>

const f = wrap(fn)
<strong>//    ^? const f: (a: number) => Promise&#x3C;Result&#x3C;string, unknown>>
</strong></code></pre>

#### Specify Error Type

By default, `wrap` won't know what error type the function is going to throw, so it will infer it as `unknown`, so that you can cast it when you are handling it. However, if you are developing a common function that want to share with others, you probably need to specify the specific error type. With the `wrap` function type definition, you can specify the error type easily.

Let's say we have a function with a signature below

```typescript
declare function fn(a: number): Promise<string>
const f = wrap(fn)
```

It will infer the wrapped type like below

```typescript
const f: (a: number) => Promise<Result<string, unknown>>
```

We want to specify the error type as `Error`. Just do below

```typescript
import {wrap} from 'unwrapit'

const f = wrap<Error, typeof fn>(fn)
```

Now the inferred type will be

```typescript
const f: (a: number) => Promise<Result<string, Error>>
```

#### Specify Both Error & Return Type

Sometimes, the function we wrapped may return `any`, we want to narrow down the return type to make it more precise. You may think of casting the function to be wrapped to the desired signature. Well, with `wrap` function type, we can just specify the return type like below

```typescript
declare function fn(a: number): Promise<any>
const f = wrap<Error, typeof fn, Promise<string>>(fn)
//    ^? const f: (a: number) => Promise<Result<string, Error>>
```

{% hint style="info" %}
Note that the given returned type should be a subtype of the function's return type, otherwise, TypeScript will complain.

```typescript
declare function fn(a: number): string
const f = wrap<Error, typeof fn, number>(fn)
//                               ^? Type 'number' does not satisfy the constraint 'string'.
```

{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://musicq.gitbook.io/unwrapit/apis/wrap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
