TypeScript 5.2의 using 선언으로 리소스 관리 개선하기

배경

최근 파일 업로드 기능을 구현하면서 임시 파일 정리가 누락되는 버그가 있었다. try-finally를 빠뜨린 게 원인이었는데, TypeScript 5.2의 using 선언이 이런 문제를 해결할 수 있다고 해서 적용해봤다.

using 선언이란

ECMAScript의 Explicit Resource Management 제안을 기반으로 한 기능이다. 스코프를 벗어날 때 자동으로 리소스를 정리해준다.

class FileHandle implements Disposable {
  constructor(private path: string) {}
  
  [Symbol.dispose]() {
    console.log(`Cleaning up ${this.path}`);
    // 파일 정리 로직
  }
}

function processFile() {
  using file = new FileHandle('/tmp/upload.txt');
  // 파일 처리 로직
  // 함수 종료 시 자동으로 dispose 호출됨
}

실제 적용 사례

DB 커넥션 풀 관리에 적용했다.

class DBConnection implements Disposable {
  private conn: Connection;
  
  async connect() {
    this.conn = await pool.getConnection();
  }
  
  [Symbol.dispose]() {
    this.conn?.release();
  }
}

async function updateUser(id: string) {
  using db = new DBConnection();
  await db.connect();
  
  // 쿼리 실행
  // 에러가 발생하든 정상 종료하든 자동으로 release
}

주의사항

  • tsconfig의 target을 es2022 이상으로 설정해야 한다
  • Symbol.dispose는 동기적으로 동작한다
  • 비동기 정리가 필요하면 Symbol.asyncDispose를 사용해야 한다
  • 아직 런타임 지원이 부족해서 polyfill이 필요할 수 있다

결과

using 도입 후 리소스 누수 관련 버그가 눈에 띄게 줄었다. finally 블록을 깜빡하는 실수를 컴파일 타임에 방지할 수 있어 만족스럽다. 다만 팀원들에게 새 문법을 설명하는 데 시간이 좀 걸렸다.