ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TypeScript의 assert 함수에 대해 ⏰
    TypeScript 2025. 8. 29. 22:49

     

    TypeScript는 정적 타입 언어로서 컴파일 시점에 타입 검사를 수행한다.

    그러나 런타임에는 타입이 존재하지 않기 때문에, 외부 입력(JSON 등)으로부터 들어오는 데이터에 대해서는 안전성을 보장하지 않는다

    이때 유용하게 활용할 수 있는 기능이 바로 Assertion Functions이다

    타입 시스템의 한계

    아래 예제를 보자

    function greet(user: { name: string }) {
      console.log(`Hello, ${user.name}`);
    }
    
    greet(JSON.parse('{"name": "Irene"}')); // 정상 작동
    greet(JSON.parse('{}')); // 런타임 에러 발생
    

    위 예제는 JSON 파싱 결과를 그대로 넘기기 때문에 컴파일 타임에서는 타입 오류가 발생하지 않지만, 실제 실행 시에는 user.name이 존재하지 않아 예외가 발생한다.

    TypeScript의 타입 시스템은 이러한 런타임 오류를 방지하지 못한다

    Assertion Function이란?

    Assertion Function은 특정 조건을 만족하지 않을 경우 예외를 발생시키며, 해당 조건을 만족하는 경우에는 타입을 좁혀주는 함수다.

    function assertIsUser(user: any): asserts user is { name: string } {
      if (typeof user !== 'object' || typeof user.name !== 'string') {
        throw new Error('Not a valid user');
      }
    }
    

    이 함수는 user가 name 속성을 가진 객체인지 확인하고, 그렇지 않으면 예외를 던지게 한다

    해당 검사를 통과하면 이후 코드에서는 user의 타입이 { name: string }으로 좁혀진다.

    const data = JSON.parse('{}');
    assertIsUser(data);
    console.log(data.name); // 타입이 안전하게 보장됨
    

    문법 설명

    function assertIsX(value: unknown): asserts value is X
    
    • asserts value is X는 "이 함수가 정상 종료되었다면 value는 X 타입이다"라는 것을 TypeScript에게 알린다.
    • 타입 가드와 유사하지만 반환값이 boolean이 아니라 void다.
    • 조건을 만족하지 않으면 반드시 throw로 종료되어야 한다.

    실전 예제 >> API 응답 타입 보호

    type User = { id: number; name: string };
    
    function assertIsUser(x: any): asserts x is User {
      if (typeof x !== 'object' || typeof x.id !== 'number' || typeof x.name !== 'string') {
        throw new Error('Invalid user');
      }
    }
    
    async function getUser() {
      const res = await fetch('/api/user');
      const data = await res.json();
      assertIsUser(data);
      return data; // 여기서 data는 User 타입으로 보장됨
    }
    

    위와 같은 방식으로 런타임의 불확실한 입력을 방어할 수 있다.

    어떤 상황에서 assert를 사용하는 것이 좋을까

    • unknown, any 타입의 값을 신뢰할 수 없을 때
    • 외부 API 응답을 사용할 때
    • 복잡한 조건에 따라 타입을 좁혀야 할 때
    • if문 등에서 타입 가드만으로는 부족한 경우

    주의할 점

    • TypeScript의 asserts 문법은 런타임 검사를 직접 구현해야 하므로, 검증 로직이 많아질 경우 유지보수가 어려울 수 있다.
    • 복잡한 객체 구조를 검사할 경우 zodio-ts 같은 런타임 타입 검사 라이브러리를 사용하는 것이 바람직할 수 있다.

     

     

     

    TypeScript의 asserts 키워드는 런타임에서 타입 안전성을 보장하는 강력한 도구다.

    타입 시스템의 한계를 보완하고, 런타임 예외를 사전에 방지할 수 있다는 점에서 큰 장점이 있다.

    특히 외부 데이터와의 인터페이스가 잦은 프로젝트에서는 적극적으로 활용할 수 있는 기능인 것 같다

Designed by Tistory.