티스토리 뷰

🌽 타입 좁히기

조건문 등을 이용해 넓은타입에서 좁은타입으로 타입을 상황에 따라 좁히는 방법
조건문을 이용해 조건문 내부에서 변수가 특정 타입임을 보장하면(더 좁은타입임을 증명하면) 타입스크립트는 이 변수의 타입을 더 좁은타입으로 자동으로 추론한다.
function func(value: number | string){
    // 밖에서 value의 타입은 number | string으로 메소드를 사용할 수 없음
    value;
    value.toFixed(); // ❌
    value.toUpperCase(); // ❌

    // value의 타입이 number -> toFixed()사용
    if(typeof value === 'number'){
        // 조건문 내부에서는 value의 타입이 number
        console.log(value.toFixed());
    } else if(typeof value === 'string'){
        // value의 타입이 string -> toUpperCase()사용
        // 조건문 내부에서는 value의 타입이 string
       console.log(value.toUpperCase()); 
    }
}

 

typeof 처럼 조건문과 함께 사용해 타입을 좁히는 표현들을 "타입 가드"라고 부르며 타입 가드를 이용해 타입을 좁혀 사용할 수 있다.

 

타입 좁히기를 활용하면 매개변수로 들어오는 여러 타입의 값에 따라 각각 다른 동작을 시키는 범용적인 함수를 만들기에 편리하다.

 

여기에 추가로 Date객체를 추가해보자.

Date 객체의 타입은 object로 조건문을 사용하여 메소드를 사용할 수 있다.

function func2(value: number | string | Date){
    if(typeof value === 'number'){
        console.log(value.toFixed());
    } else if(typeof value === 'string'){
       console.log(value.toUpperCase()); 
    } else if(typeof value === 'object'){
        // value의 타입이 Date(Date 객체 -> object) -> getTime() 사용
        console.log(value.getTime());
    }
}

 

하지만 여기에 null 타입을 추가하면 오류가 발생한다. 

typeof 에 null을 넣으면 똑같이 object를 반환하기 때문에 null또한 object에 해당되기 때문이다.

function func2(value: number | string | Date | null){
    if(typeof value === 'number'){
        console.log(value.toFixed());
    } else if(typeof value === 'string'){
       console.log(value.toUpperCase()); 
    } else if(typeof value === 'object'){
        console.log(value.getTime()); // ❌ -> value는 null이 들어갈 수 있음
    }
}

 

 

🛡️ instanceof 타입가드

내장 클래스 타입을 보장할 수 있는 타입가드를 만들 수 있다.
A instanceof B

A가 B에 속해있다면 true를 아니라면 false를 반환한다.

function func3(value: number | string | Date | null){
    // value의 타입이 number -> toFixed()사용
    if(typeof value === 'number'){
        // 조건문 내부에서는 value의 타입이 number
        console.log(value.toFixed());
    } else if(typeof value === 'string'){
        // value의 타입이 string -> toUpperCase()사용
        // 조건문 내부에서는 value의 타입이 string
       console.log(value.toUpperCase()); 
    } else if(value instanceof Date){
        // value가 Date 객체라면 -> true , 아니면 -> false
        console.log(value.getTime());
    }
}

value가 Date객체에 속하기 때문에 에러가 발생하지 않는다.

그러나 instanceof는 내장 클래스 또는 직접 만든 클래스에서만 사용이 가능한 연산으로 우리가 직접 만든 타입과 함께 사용하는 것은 불가능하다.

type Person = {
    name:string;
    age:number;
};
function func4(value: number | string | Date | null | Person){
    if(typeof value === 'number'){
        console.log(value.toFixed());
    } else if(typeof value === 'string'){
       console.log(value.toUpperCase()); 
    } else if(value instanceof Date){
        console.log(value.getTime());
    } else if(value instanceof Person){
        // ❌ -> Person은 형식만 참조하지만, 여기서는 값으로 사용되고 있음
    }
}

 

 

🛡️ in 타입 가드

직접 만든 타입과 함께 사용하기 위해서는 In 연산자를 사용해야 한다.

프로퍼티 in 파라미터
type Person = {
    name:string;
    age:number;
};

function func4(value: number | string | Date | null | Person){
    if(typeof value === 'number'){
        console.log(value.toFixed());
    } else if(typeof value === 'string'){
       console.log(value.toUpperCase()); 
    } else if(value instanceof Date){
        console.log(value.getTime());
    } else if(value && 'age' in value){
        // 'age' in value만 하는 경우 null도 포함되기 때문에 value가 존재함을 표시
       console.log(`${value.name}은 ${value.age}살 입니다.`) 
    }
}

Person 타입에 들어가는 프로퍼티 age가 value에 포함되는지만을 조건으로 한다면 null을 포함하기 때문에 값이 존재한다는 표시를 해야한다.

 


🔗 타입스크립트 강의

 

한 입 크기로 잘라먹는 타입스크립트 - 인프런 | 강의

문법을 넘어 동작 원리와 개념 이해까지 배워도 배워도 헷갈리는 타입스크립트 이제 제대로 배워보세요! 여러분을 타입스크립트 마법사🧙🏻‍♀️로 만들어드립니다., 프론트엔드의 피할 수

www.inflearn.com

 

728x90