TypeScript(타입스크립트) 유니언과 교차 타입

NSH·2022년 5월 30일
0

TypeScript

목록 보기
5/8

1. 유니언 타입(Union Types)

numberstring 을 매개변수로 기대하는 라이브러리가 존재한다고 가정해보자.

/**
 * 만약 'padding'이 문자열이라면, 'padding'은 왼쪽에 더해질 것입니다.
 * 만약 'padding'이 숫자라면, 그 숫자만큼의 공백이 왼쪽에 더해질 것입니다.
 */

function paddingLeft(value: string, padding: any) {
	if(typeof padding === 'number') {
    	return Array(padding + 1).join(" ") + value;
    }
  
  	if(typeof padding === 'string') {
    	return padding + value;
    }
  
  	new Error(`Expected string or number, got '${padding}'.`);
}

paddingLeft("Hello World", 4);

paddingLeft 함수의 매개변수인 paddingany 타입으로 되어있다. numberstring 이 아닌 인자로 함수를 호출할 수 있다는 뜻이고, 타입스크립트는 paddingany 타입이기 때문에 타입 검사를 안하기 때문에 문제가 없다고 받아들일 것이다.

any 타입 대신에 유니언 타입을 사용해서 padding 매개변수의 타입을 정의할 수 있다.

function paddingLeft(value: string, padding: number | string) {
	// ... 
}

유니언 타입은 여러 타입 중에 하나가 될 수 있는 값을 의미한다. 세로 막대(|) 로 각 타입을 구분하여 작성할 수 있다.

2. 공통 필드를 갖는 유니언(Unions with Common Fields)

유니언 타입인 값이 존재하면, 모든 타입의 공통인 맴버들에만 접근이 가능하다.

interface Bird {
	fly(): void;
  	layEgges(): void;
}

interface Fish {
	swim(): void;
  	layEgges(): void;
}

declare function getSmallPat(): Fish | Bird;

let pet = getSmallPat();
pet.layEgges(); // 정상, 두 인터페이스가 공통으로 가지고 있으므로 접근 가능
pet.swim(); 	// 오류, 두 인터페이스가 공통으로 가지고 있지 않으므로 접근 불가

3. 유니언 구별(Discriminating Unions)

타입 추론의 범위를 좁혀나가게 해줄 수 있는 리터럴 타입을 갖는 단일 필드를 사용해서 유니언을 구분할 수 있다.

아래 타입 들은 state 를 가지고 그들 각자만의 필드도 존재한다. 리터럴 타입으로 state 를 갖고 있다면 state 는 동일한 문자열과 대조되고 이후에는 타입스크립트는 현재 어떤 타입이 사용되고 있는지 알 수 있다.

interface NetworkLoadingState {
	state: "loading";
}
interface NetworkFailedState {
	state: "failed";
  	code: number;
}
interface NetworkSuccessState {
	state: "success";
  	response: {
    	title: string;
      	duration: string;
      	summary: string;
    }
}

type NetworkState = 
	| NetworkLoadingState
	| NetworkFailedState
	| NetworkSuccessState;

function networkState(state: NetworkState): string {
	switch(state.state) {
      case "loading": 
        return 'loading.....';
      case "failed": 
        return `Error ${state.code}`
      case "success": 
        return `${state.response.title} - ${state.response.summary}`
    }
}

4. 교차 타입(Intersection Types)

교차 타입은 여러 타입을 하나로 결합한다. 기존 타입들을 합쳐서 필요한 기능을 모두 가진 단일 타입을 얻을 수 있다.

예를 들어, 일관된 에러를 다루는 경우 에러 핸들링을 분리해서 하나의 응답 타입에 결합된 자체 타입으로 만들어 사용할 수 있다.

interface ErrorHandling {
	success: beelean;
  	error?: {
    	message: string;
    }
}

interface UsersData {
	users: {
    	name: string;
    }
}

interface PostsData {
	posts: {
    	title: string;
    }
}

type UsersResponse = UsersData & ErrorHandling;
type PostsResponse = PostsData & ErrorHandling;

const handleUsersResponse = (response: UsersResponse) => {
	if(response.error) {
    	console.error('error : ', response.error);
      	return;
    }
  
  console.log('users : ', response.users);
}
profile
잘 하고 싶다.

0개의 댓글