Skip to content

Instantly share code, notes, and snippets.

@t3dotgg
Last active September 11, 2026 06:13
Show Gist options
  • Select an option

  • Save t3dotgg/a486c4ae66d32bf17c09c73609dacc5b to your computer and use it in GitHub Desktop.

Select an option

Save t3dotgg/a486c4ae66d32bf17c09c73609dacc5b to your computer and use it in GitHub Desktop.
Theo's preferred way of handling try/catch in TypeScript
// Types for the result object with discriminated union
type Success<T> = {
data: T;
error: null;
};
type Failure<E> = {
data: null;
error: E;
};
type Result<T, E = Error> = Success<T> | Failure<E>;
// Main wrapper function
export async function tryCatch<T, E = Error>(
promise: Promise<T>,
): Promise<Result<T, E>> {
try {
const data = await promise;
return { data, error: null };
} catch (error) {
return { data: null, error: error as E };
}
}
@Pnlvfx

Pnlvfx commented Aug 21, 2026

Copy link
Copy Markdown
// Types for the result object with discriminated union
interface Success<T> {
  data: T;
  error?: undefined;
}

interface Failure<E> {
  data?: undefined;
  error: E;
}

type Result<T, E = Error> = Success<T> | Failure<E>;

// Main wrapper function
export async function tryCatch<T, E = Error>(promise: Promise<T>): Promise<Result<T, E>> {
  try {
    const data = await promise;
    return { data };
  } catch (error) {
    // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
    return { error: error as E };
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment