or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array.mdcompat.mderror.mdfunction.mdindex.mdmath.mdobject.mdpredicate.mdpromise.mdstring.mdutil.md
tile.json

util.mddocs/

Utility Functions

Essential utility functions for error handling, assertions, and safe function execution. These utilities provide robust patterns for handling failures and ensuring application reliability.

Capabilities

Attempt Function

Safely executes a function and returns a tuple containing either the result or the error, following the "never throw" pattern common in functional programming.

/**
 * Attempt to execute a function and return the result or error.
 * Returns a tuple where:
 * - On success: [null, Result] - First element is null, second is the result
 * - On error: [Error, null] - First element is the caught error, second is null
 */
function attempt<T, E>(func: () => T): [null, T] | [E, null];

Usage Examples:

import { attempt } from 'es-toolkit/util';

// Successful execution
const [error, result] = attempt(() => 42);
// [null, 42]

// Failed execution
const [error, result] = attempt(() => {
  throw new Error('Something went wrong');
});
// [Error, null]

// With type parameter
const [error, names] = attempt<string[]>(() => ['Alice', 'Bob']);
// [null, ['Alice', 'Bob']]

// Safe JSON parsing
const [parseError, data] = attempt(() => JSON.parse(jsonString));
if (parseError) {
  console.error('Invalid JSON:', parseError.message);
} else {
  console.log('Parsed data:', data);
}

Attempt Async Function

Safely executes an async function and returns a Promise that resolves to a tuple containing either the result or the error.

/**
 * Attempt to execute an async function and return the result or error.
 * Returns a Promise that resolves to a tuple where:
 * - On success: [null, Result] - First element is null, second is the result
 * - On error: [Error, null] - First element is the caught error, second is null
 */
function attemptAsync<T, E>(func: () => Promise<T>): Promise<[null, T] | [E, null]>;

Usage Examples:

import { attemptAsync } from 'es-toolkit/util';

// Successful execution
const [error, data] = await attemptAsync(async () => {
  const response = await fetch('https://api.example.com/data');
  return response.json();
});
// If successful: [null, { ... data ... }]

// Failed execution
const [error, data] = await attemptAsync(async () => {
  throw new Error('Network error');
});
// [Error, null]

// With type parameter
const [error, users] = await attemptAsync<User[]>(async () => {
  const response = await fetch('https://api.example.com/users');
  return response.json();
});
// users is typed as User[]

// Safe API call pattern
async function fetchUserData(userId: string) {
  const [error, userData] = await attemptAsync(async () => {
    const response = await fetch(`/api/users/${userId}`);
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    return response.json();
  });

  if (error) {
    console.error('Failed to fetch user:', error.message);
    return null;
  }

  return userData;
}

Invariant Function

Asserts that a given condition is true. If the condition is false, an error is thrown with the provided message or error object. Provides TypeScript assertion support for type narrowing.

/**
 * Asserts that a given condition is true. If the condition is false, an error is thrown.
 * Supports both string messages and Error objects.
 */
function invariant(condition: unknown, message: string): asserts condition;
function invariant(condition: unknown, error: Error): asserts condition;
function invariant(condition: unknown, message: string | Error): asserts condition;

Usage Examples:

import { invariant } from 'es-toolkit/util';

// Basic assertion with string message
invariant(user.isAuthenticated, 'User must be authenticated');

// Custom error object
class ValidationError extends Error {
  constructor(field: string) {
    super(`Validation failed for field: ${field}`);
    this.name = 'ValidationError';
  }
}

invariant(email.includes('@'), new ValidationError('email'));

// Type narrowing in TypeScript
function processUser(user: User | null) {
  invariant(user !== null, 'User cannot be null');
  // TypeScript now knows user is not null
  console.log(user.name); // No type error
}

// Ensuring conditions during development
function divide(a: number, b: number): number {
  invariant(b !== 0, 'Division by zero is not allowed');
  return a / b;
}

// Ensuring object properties exist
function getUsername(config: { user?: { name?: string } }) {
  invariant(config.user, 'User configuration is required');
  invariant(config.user.name, 'Username is required');
  // TypeScript knows config.user.name is defined
  return config.user.name;
}

Assert Function

Alias for the invariant function, providing familiar Node.js-style assertion API.

/**
 * Assert function - alias for invariant
 * Asserts that a given condition is true. If the condition is false, an error is thrown.
 */
function assert(condition: unknown, message: string | Error): asserts condition;

Usage Examples:

import { assert } from 'es-toolkit/util';

// Node.js-style assertions
assert(process.env.NODE_ENV, 'NODE_ENV must be defined');
assert(typeof port === 'number', 'Port must be a number');

// Development-time checks
function createConnection(config: DatabaseConfig) {
  assert(config.host, 'Database host is required');
  assert(config.port > 0, 'Database port must be positive');
  
  // Connection logic here
}

Error Handling Patterns

These utility functions enable robust error handling patterns:

Safe Operations:

// Instead of try/catch blocks everywhere
const [error, result] = attempt(() => riskyOperation());
if (error) {
  handleError(error);
} else {
  useResult(result);
}

Async Safe Operations:

// Clean async error handling
const [error, data] = await attemptAsync(() => fetchData());
if (error) {
  return { success: false, error };
}
return { success: true, data };

Defensive Programming:

// Ensure preconditions are met
function processPayment(amount: number, currency: string) {
  invariant(amount > 0, 'Payment amount must be positive');
  invariant(currency.length === 3, 'Currency must be 3-letter code');
  
  // Process payment with confidence
}