Skip to content

TypeScript에서의 에러 처리 (Error Handling) ​

TypeScript의 에러 처리는 기본적으로 JavaScript의 예외 처리 메커니즘을 기반으로 하지만, 타입 시스템을 통해 에러 객체를 더 안전하게 다룰 수 있는 방법을 제공한다.


1. 기본 구조 try / catch / finally ​

try 블록에서 에러가 발생하면, 제어 흐름이 catch 블록으로 이동하며, finally 블록은 에러 발생 여부와 상관없이 항상 실행된다.

ts
try {
  // 에러가 발생할 수 있는 코드
  fn(); // throw new Error("Something went wrong")
} catch (error) {
  console.error(error.message);
} finally {
  console.log("항상 실행됩니다.");
}
  • finally 블록은 리소스 정리, 상태 복구 등의 역할을 할 때 유용하다.

2. unknown 타입으로 안전하게 에러 처리하기 ​

TypeScript는 catch 블록의 매개변수 타입을 자동으로 unknown으로 추론한다.
“에러가 어떤 타입인지 확실하지 않다”는 의미이며, 명시적인 타입 좁히기를 통해 안전하게 다뤄야 한다.

ts
function checkPositiveNumber(num: number) {
  if (num < 0) {
    throw new Error("number should be positive");
  }

  console.log(`${num} is a positive number`);
}

try {
  checkPositiveNumber(10);
  checkPositiveNumber(-10);
} catch (error: unknown) {
  // 타입 좁히기
  if (error instanceof Error) {
    console.error(error.message);
  }
}
  • instanceof를 이용해 런타임에서 에러 타입을 좁혀야 .message 등의 프로퍼티 접근이 타입 안전하게 보장된다.

3. 사용자 정의 에러 클래스 (Custom Error) ​

에러를 구체적으로 구분하거나, 도메인에 맞는 의미 있는 에러를 표현하려면 사용자 에러 클래스를 사용하는 것이 좋다.

ts
class CustomError extends Error {
  constructor(message: string) {
    super(message);
    this.name = "CustomError"; // 에러 이름 명시
  }
}

try {
  throw new CustomError("custom error..");
} catch (error) {
  if (error instanceof CustomError) {
    console.error(error.message); // custom error..
  }
}
  • this.name을 지정하면 스택 추적이나 로깅 시 에러 식별이 명확해진다.

TypeScript에서는 런타임 에러를 완전히 막을 수는 없지만,

타입 시스템을 통해 에러 객체의 형태를 명확히 정의함으로써 더 안정적이고 예측 가능한 예외 처리 로직을 작성할 수 있다.