Error Handling in TypeScript
Jun 24, 2025I’m not very familiar with TypeScript patterns for handling errors. I was wondering what would be an interesting way to define domain-specific error types so that I can be very specific on what happened inside a function execution.
Consider a createUser
function that creates a user. We can create a generic Rust-like Result
type:
type Result<T, E> =
| { success: true; value: T }
| { success: false; error: E };
Then define domain-specific error types as a discriminated union:
type CreateUserError =
| { type: 'EmailAlreadyExists'; email: string }
| { type: 'InvalidEmailFormat'; email: string }
| { type: 'WeakPassword'; reason: string };
Our createUser
function becomes:
function createUser(email: string, password: string): Result<User, CreateUserError> {
if (!isValidEmail(email)) {
return { success: false, error: { type: 'InvalidEmailFormat', email } };
}
if (!isStrongPassword(password)) {
return { success: false, error: { type: 'WeakPassword', reason: 'Too short' } };
}
if (emailExists(email)) {
return { success: false, error: { type: 'EmailAlreadyExists', email } };
}
const user = new User(email, password);
return { success: true, value: user };
}