본문 바로가기
TypeScript

[패턴] Discriminating unions - To narrow down the type within a union type = 타입 가드

by 찬찬2 2024. 6. 5.
type LocationState = {
    state: 'Loading' | 'Success' | 'Error'
    coordinate?: {
        lat: number,
        lan: number
    }
    error?: {
        message: string
    }
}

/*
* state 가 loading 일때는 coordinate 와 error 이 필요없다.
* state 가 success 일때는 error 이 필요없다.
* state 가 error 일때는 coordinate 가 필요없다.
* 위와 같이 옵셔널로 타입을 지정했을때 문제는...
*/

function printLocation(location: LocationState){
    switch(location.state){
        case 'Loading' :
            console.log(location.state);
        break;
        case 'Success' :
            console.log(location.coordinate.lat, location.coordinate.lan); // 에러: 'location.coordinate' is possibly 'undefined'.
        break;
        case 'Error' :
            console.log(location.error.message); // 에러: 'location.error' is possibly 'undefined'.
        break;
    }
}

 

type LoadingLocationState = {
    state: 'Loading'
}

type SuccessLocationState = {
    state: 'Success'
    coordinate: {
        lat: number
        lan: number
    }
}

type ErrorLocationState = {
    state: 'Error'
    error: {
        message: string
    }
}

type LocationState = LoadingLocationState | SuccessLocationState | ErrorLocationState

function printLocation(location: LocationState){
    switch(location.state){
        case 'Loading' :
            console.log(location.state);
        break;
        case 'Success' :
            console.log(location.coordinate.lat, location.coordinate.lan);
        break;
        case 'Error' :
            console.log(location.error.message);
        break;
    }
}

 

type LoadingLocationState = {
    state: string
}

type SuccessLocationState = {
    state: string
    coordinate: {
        lat: number
        lan: number
    }
}

type ErrorLocationState = {
    state: number
    error: {
        message: string
    }
}

type LocationState = LoadingLocationState | SuccessLocationState | ErrorLocationState

function printLocation(location: LocationState){
	if(typeof location.state === 'string'){
        // 위 세가지 중 하나를 읽지 못한다. 원했던 결과는... 만약 location.state 가 string일 경우,
        // LoadingLocationState 또는 SuccessLocationState 가 가지고 있는 프로퍼티를 읽어내는 것.
		console.log(location);
    }
}

댓글