# @guialves/tuple

A lightweight TypeScript utility that converts Promises into Go-style `[data, error]` tuples for cleaner error handling.

## Why?

Traditional Promise error handling with try/catch can lead to nested code and repetitive patterns:

```typescript
// Traditional approach
try {
  const user = await fetchUser(id);
  try {
    const posts = await fetchUserPosts(user.id);
    // Handle success
  } catch (postsError) {
    // Handle posts error
  }
} catch (userError) {
  // Handle user error
}
```

With `tuple`, you get a cleaner, more functional approach:

```typescript
// With tuple
const [user, userError] = await tuple(fetchUser(id));
if (userError) {
  // Handle user error
  return;
}

const [posts, postsError] = await tuple(fetchUserPosts(user.id));
if (postsError) {
  // Handle posts error
  return;
}

// Handle success - both user and posts are guaranteed to be non-null here
```

## Installation

```bash
npm install @guialves/tuple
```

## Usage

### Basic Example

```typescript
import { tuple } from '@guialves/tuple';

async function example() {
  const [data, error] = await tuple(fetch('/api/users'));
  
  if (error) {
    console.error('Request failed:', error);
    return;
  }
  
  // data is guaranteed to be non-null here
  console.log('Success:', data);
}
```

### With TypeScript

The function is fully typed and will infer the correct types:

```typescript
import { tuple } from '@guialves/tuple';

interface User {
  id: number;
  name: string;
}

async function getUser(id: number): Promise<User> {
  // ... implementation
}

async function example() {
  // TypeScript infers: [User | null, any]
  const [user, error] = await tuple(getUser(1));
  
  if (error) {
    // Handle error
    return;
  }
  
  // user is of type User here (not null)
  console.log(user.name);
}
```

### Multiple Async Operations

```typescript
import { tuple } from '@guialves/tuple';

async function processUserData(userId: number) {
  const [user, userError] = await tuple(fetchUser(userId));
  if (userError) return { error: 'Failed to fetch user' };
  
  const [profile, profileError] = await tuple(fetchProfile(user.id));
  if (profileError) return { error: 'Failed to fetch profile' };
  
  const [posts, postsError] = await tuple(fetchPosts(user.id));
  if (postsError) return { error: 'Failed to fetch posts' };
  
  return {
    user,
    profile,
    posts
  };
}
```

## API

### `tuple<T>(promise: Promise<T>): Promise<[T | null, any]>`

Converts a Promise into a tuple where:
- First element: the resolved value (or `null` if rejected)
- Second element: the error (or `null` if resolved)

**Parameters:**
- `promise`: Any Promise to be converted

**Returns:**
- `Promise<[T | null, any]>`: A Promise that resolves to a tuple

## Benefits

- **No try/catch blocks**: Eliminates the need for try/catch statements
- **Explicit error handling**: Forces you to handle errors explicitly
- **Functional style**: Promotes a more functional programming approach
- **Type safety**: Full TypeScript support with proper type inference
- **Lightweight**: Zero dependencies, minimal footprint
- **Go-inspired**: Familiar pattern for developers coming from Go

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Repository

[https://github.com/justAlves/tuple](https://github.com/guialves/tuple)