ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 타입가드 사용하여 안전하게 타입스크립트 타이핑하기
    TypeScript 2024. 8. 4. 00:20

    타입스크립트에서 타입 가드는 런타임에 변수의 타입을 확인하고, 이를 통해 타입스크립트가 해당 변수의 타입을 특정 블록 안에서 더 정확하게 추론할 수 있도록 돕는 방법이다.

     

    타입 가드를 잘 활용하면 코드의 타입 안전성을 높이고, 가독성과 유지보수성을 향상시킬 수 있다.

     

    때문에 타입가드를 잘 사용하는 것은 타입스크립트에서 중요하다.

    타입가드에 어떤 방법들이 있는지 확인하고, 어떤 방법을 사용하는 것이 좋을지 알아보았다.

     

    1. 타입 단언(`as` 키워드) - 추천하지 않음


    타입 단언은 변수의 타입을 명시적으로 지정하는 방법이다.

    let str: string | undefined;
    str = "Hi" as string;

     

    그러나 런타임에 아무런 검사를 하지 않기 때문에 잘못된 단언으로 인해 런타임 에러를 유발할 수 있다.

    따라서 가능한 한 사용을 피하는 것이 좋다.

    function processValue(value: string | number) {
        if ((value as string).toUpperCase) {
            // Here we are asserting that value is a string
            console.log(`String value in uppercase: ${(value as string).toUpperCase()}`);
        } else {
            // Here we are asserting that value is a number
            console.log(`Number value: ${value as number}`);
        }
    }
    
    processValue("hello");
    processValue(100);


    위 예제에서 `value as string` 또는 `value as number`로 타입을 단언하고 있다. 

    그러나, 이 경우는 개발자가 모든 타입에 대한 확신을 가지지 않는 경우 타입 안정성이 보장되지 않을 가능성이 있다.

     

    때문에 이 방법은 타입 안전성을 보장하지 않기 때문에 추천되지 않는다.

    2. `typeof` 타입 가드 - 원시 타입에 유용


    `typeof` 연산자는 원시 타입(primitive type)을 확인할 때 사용된다. 

    주로 문자열, 숫자, 불리언 등 원시 타입을 구분할 때 유용하다.

    function printValue(value: string | number) {
        if (typeof value === 'string') {
            // value is treated as a string here
            console.log(`String value: ${value}`);
        } else {
            // value is treated as a number here
            console.log(`Number value: ${value}`);
        }
    }
    
    printValue("Hello");
    printValue(42);


    `typeof` 연산자는 타입을 정확히 구분할 수 있어 원시 타입을 다룰 때 유용하지만, 객체 타입에는 사용할 수 없다.

     

    그리고 배열은 object 타입으로 판단되기에 Array.isArray() 같은 메서드를 활용해야 하는 등 추가로 고려해야할 사항이 많다.

    3. `instanceof` 타입 가드 - 클래스 인스턴스에 유용


    `instanceof` 연산자는 객체가 특정 클래스의 인스턴스인지 확인할 때 사용된다.

    👻  instanceof는 참고로 타입스크립트 문법이 아닌, 자바스크립트 문법이다. mdn 문서

     

    클래스 기반 객체를 구분하는 데 유용하다.

    class Dog {
        bark() {
            console.log('Woof!');
        }
    }
    
    class Cat {
        meow() {
            console.log('Meow!');
        }
    }
    
    function makeSound(animal: Dog | Cat) {
        if (animal instanceof Dog) {
            // animal is treated as Dog here
            animal.bark();
        } else {
            // animal is treated as Cat here
            animal.meow();
        }
    }
    
    const dog = new Dog();
    const cat = new Cat();
    
    makeSound(dog);
    makeSound(cat);


    `instanceof` 연산자는 클래스 기반 객체의 타입을 확인할 때 유용하지만, 인터페이스나 타입 별칭으로 정의된 타입에는 사용할 수 없다.

    4. 커스텀 타입 가드 함수 - 가장 유연하고 강력 ✨


    가장 추천하는 방법은 커스텀 타입 가드 함수를 사용하는 것이다. 

    이 방법은 특정 타입을 정의하고 확인할 수 있는 가장 유연하고 강력한 방법이다.

    interface Fish {
        swim(): void;
    }
    
    interface Bird {
        fly(): void;
    }
    
    function isFish(pet: Fish | Bird): pet is Fish {
        return (pet as Fish).swim !== undefined;
    }
    
    function move(pet: Fish | Bird) {
        if (isFish(pet)) {
            // pet is treated as Fish here
            pet.swim();
        } else {
            // pet is treated as Bird here
            pet.fly();
        }
    }
    
    const fish: Fish = {
        swim() {
            console.log('Fish is swimming');
        }
    };
    
    const bird: Bird = {
        fly() {
            console.log('Bird is flying');
        }
    };
    
    move(fish);
    move(bird);


    위 예제에서 `isFish` 함수는 커스텀 타입 가드 함수로, `pet`이 `Fish` 타입인지 확인한다. 

    이 방법은 타입스크립트가 타입을 정확하게 추론할 수 있도록 도와주며, 코드의 가독성과 유지보수성을 크게 향상시킨다.

    또한 타입가드는 배열의 .filter 고차함수와 함께 사용될 수 있다.

    const strArr: (string | undefined)[] = ['hi', 'bye'];
    
    function isString(item: unknown): item is string {
        return typeof item === 'string';
    }
    
    const checkedStrArr = strArr.filter(isString); // string[]

     

    이렇게 순수한 string 배열을 얻을 수도 있다.

     

    👻 타입스크립트에서 타입 가드를 사용하면 코드의 타입 안전성을 높일 수 있다. 

    • `as` 키워드를 사용한 타입 단언은 피하는 것이 좋다.
    • `typeof`와 `instanceof` 연산자는 원시 타입과 클래스 인스턴스를 구분할 때 유용하다. (제한적인 사용법)
    • 가장 추천하는 방법은 커스텀 타입 가드 함수를 사용하는 것으로, 이를 통해 타입스크립트가 타입을 정확하게 추론하고, 더 안전한 코드를 작성할 수 있다.
Designed by Tistory.