icon안동민 개발노트

특수 타입 (any, unknown, never, void)


 타입스크립트는 일반적인 타입 외에도 특수한 목적을 가진 타입들을 제공합니다.

 이들은 any, unknown, never, void 타입으로, 각각 고유한 특성과 사용 사례를 가지고 있습니다.

any 타입

 any 타입은 모든 타입의 상위 타입으로, 어떤 값이든 할당할 수 있습니다.

let anyValue: any = 5;
anyValue = "string";
anyValue = true;
anyValue = { x: 1 };

 장점

  • 기존 자바스크립트 코드와의 호환성
  • 타입을 알 수 없는 값을 다룰 때 유용

 단점

  • 타입 안정성 상실
  • 컴파일러의 타입 체크 무력화

unknown 타입

 unknownany와 유사하지만 더 안전한 타입입니다.

let unknownValue: unknown = 10;
unknownValue = "hello";
unknownValue = [1, 2, 3];
 
// 사용 전 타입 체크 필요
if (typeof unknownValue === "string") {
    console.log(unknownValue.toUpperCase());
}

 any와의 차이점

  • unknown 타입의 값은 직접 사용할 수 없음
  • 타입 체크 후 사용 가능

never 타입

 never 타입은 절대 발생할 수 없는 타입을 나타냅니다.

// 항상 예외를 던지는 함수
function throwError(message: string): never {
    throw new Error(message);
}
 
// 무한 루프
function infiniteLoop(): never {
    while (true) {}
}

 사용 사례

  • 절대 반환하지 않는 함수의 반환 타입
  • 타입 좁히기에서 남은 케이스가 없음을 나타냄

void 타입

 void는 주로 반환 값이 없는 함수의 반환 타입으로 사용됩니다.

function logMessage(message: string): void {
    console.log(message);
}

 voidundefined의 관계

  • void 함수에서 undefined를 반환해도 됨
  • void는 타입으로, undefined는 값임

특수 타입의 영향

 1. 코드 안정성

  • any 사용 시 안정성 저하
  • unknownnever는 안정성 향상

 2. 가독성

  • 적절히 사용 시 코드의 의도를 명확히 전달
  • 과도한 사용은 오히려 가독성 저하

타입 가드와 unknown

 unknown 타입을 구체적인 타입으로 좁히는 방법

function processValue(value: unknown): string {
    if (typeof value === "string") {
        return value.toUpperCase();
    } else if (typeof value === "number") {
        return value.toFixed(2);
    }
    throw new Error("Unsupported type");
}

never를 이용한 완전성 검사

type Shape = Circle | Square;
 
function getArea(shape: Shape) {
    switch (shape.kind) {
        case "circle":
            return Math.PI * shape.radius ** 2;
        case "square":
            return shape.sideLength ** 2;
        default:
            // 모든 케이스를 처리했다면 여기에 도달하지 않음
            const _exhaustiveCheck: never = shape;
            return _exhaustiveCheck;
    }
}

 이 기법의 유용성

  • 새로운 타입이 추가될 때 컴파일 에러 발생
  • 모든 케이스 처리 보장

any 사용 최소화 전략

  1. unknown 타입 활용
  2. 유니온 타입 사용
  3. 제네릭 활용
  4. 타입 단언 대신 타입 가드 사용

 예시

// any 대신 unknown 사용
function parseJSON(jsonString: string): unknown {
    return JSON.parse(jsonString);
}
 
// 사용 시 타입 체크
const data = parseJSON('{"name": "John"}');
if (typeof data === "object" && data !== null && "name" in data) {
    console.log(data.name);
}

특수 타입의 역할과 중요성

  1. any : 점진적 타입 적용, 레거시 코드 통합
  2. unknown : 타입 안정성과 유연성의 균형
  3. never : 타입 시스템의 완전성 보장
  4. void : 함수 반환 타입의 명확한 표현

Best Practices와 주의사항

  1. any 사용 최소화
  2. unknownany의 대안으로 고려
  3. 함수가 값을 반환하지 않을 때 void 사용
  4. never를 활용한 철저한 타입 체크
  5. 타입 가드를 통한 타입 좁히기 적극 활용

 타입스크립트의 특수 타입들은 각각 고유한 목적과 사용 사례를 가지고 있습니다. any 타입은 가장 유연한 타입으로, 어떤 값이든 할당할 수 있지만, 이는 타입 안정성을 해칠 수 있습니다. 따라서 any 타입의 사용은 최소화하고, 불가피한 경우에만 제한적으로 사용해야 합니다.

 unknown 타입은 any의 안전한 대안으로, 모든 값을 할당할 수 있지만 사용하기 전에 반드시 타입을 체크해야 합니다. 이는 타입 안정성을 유지하면서도 유연성을 제공합니다. 타입 가드를 사용하여 unknown을 더 구체적인 타입으로 좁히는 방법은 코드의 안정성을 크게 향상시킵니다.

 never 타입은 절대 발생할 수 없는 타입을 나타내며, 주로 항상 예외를 던지는 함수나 무한 루프 함수의 반환 타입으로 사용됩니다. 또한, never를 활용한 완전성 검사는 switch 문이나 조건문에서 모든 가능한 케이스를 처리했는지 확인하는 데 매우 유용합니다.

 void 타입은 주로 반환 값이 없는 함수의 반환 타입으로 사용됩니다. voidundefined는 비슷해 보이지만, void는 타입이고 undefined는 값이라는 점에서 차이가 있습니다.

 이러한 특수 타입들을 적절히 활용하면 코드의 안정성과 가독성을 크게 향상시킬 수 있습니다. any의 사용을 최소화하고 대신 unknown을 활용하거나, 더 구체적인 타입을 사용하는 것이 좋습니다. 타입 가드를 통해 unknown 타입을 좁히는 방법은 타입 안정성을 유지하면서도 유연한 코드를 작성할 수 있게 해줍니다.

 never 타입을 활용한 완전성 검사는 특히 유니온 타입을 다룰 때 매우 유용합니다. 이를 통해 모든 가능한 케이스를 처리했는지 컴파일 시점에 확인할 수 있어, 런타임 오류를 크게 줄일 수 있습니다.

 특수 타입들은 타입스크립트의 타입 시스템을 더욱 강력하고 표현력 있게 만듭니다. any는 점진적 타입 적용이나 레거시 코드 통합 시 유용하게 사용될 수 있지만, 가능한 한 구체적인 타입을 사용하는 것이 좋습니다. unknown은 타입 안정성과 유연성 사이의 균형을 제공하며, never는 타입 시스템의 완전성을 보장하는 데 중요한 역할을 합니다. void는 함수의 반환 타입을 명확하게 표현하는 데 사용됩니다.

 결론적으로, 이러한 특수 타입들을 효과적으로 활용하기 위해서는 각 타입의 특성과 용도를 잘 이해하고, 적절한 상황에서 사용하는 것이 중요합니다. any 사용을 최소화하고, unknown을 대안으로 고려하며, 함수가 값을 반환하지 않을 때는 void를 사용하고, never를 활용한 철저한 타입 체크를 수행하는 등의 Best Practices를 따르면 더욱 안전하고 유지보수가 용이한 코드를 작성할 수 있습니다.