Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

바스키아

TypeScript) Intersection & Union Types 본문

JS/TypeScript

TypeScript) Intersection & Union Types

바스키아1 2019. 9. 12. 16:43

Intersection 타입?? 영어가 약하므로 우선

횡단, 교차?

우선 예제로 보자

1
2
3
4
5
6
7
8
9
10
interface User {
    name: string;
}
interface Action {
    do() : void;
}
 
function createUserAction(u: User, a: Action) {
    return { ...u, ...a};
}

우선 두 interface 를 합치는 함수가 있다고 하자.

그럼 저 리턴값에 대한 타입을 정의할때 

interface Sum{
	name:string;
    do() : void
}

따로 인터페이스를 만들어서

function createUserAction(u: user, a: Action) : Sum{
	return {...u, ...a}
}

이렇게 리턴타입을 정해줘야하는거니?? ---> 이럴때 intersection 을 쓰라는 것이다. & 엔드 쓰라고!!

1
2
3
4
5
6
7
8
9
10
interface User {
    name: string;
}
interface Action {
    do() : void;
}
 
function createUserAction(u: User, a: Action) : User & Action {
    return { ...u, ...a};
}

요렇게.... ㅎㅎ ( 이러면 타입들을 모아놓은 interface 파일이 좀 줄어들겠네 ㅎㅎ)

 

 

그러면 이제 Union Types은 무엇인가....

합..친다?? 

이것도 예제를 봅시다. 만약 두값을 교하는 함수가 있다고 합시다.

1
2
3
function compare(x: string | number, y: string | number) {
 
}    

파라미터 타입이 이상하다? ----> "|" 라는 or 연산자를 사용해서 x에 문자열 또는 number가 받아질수 있다는 것을 암시한다. 

or 기호를 사용해서 표현하는 것이 union Types

x.를 확인하면 다음과 같은 파라미터 타입을 받는다는 설명이 뜬다

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function compare(x: string | number, y: string | number) {
    if(typeof x === 'number' && typeof y ==='number'){
    return x === y ? 0 : x > y ? 1 : -1;
    }
    if(typeof x === 'string' && typeof y ==='string'){
return '위에와 같지뭐 ㅎㅎ';
    }
    throw Error('not supported type');
}    
 
const v = compare(1,2);
 
const v = compare("a","b");
 
const v = compare("a",2);

typeof 로 파라미터 타입을 구분하여 함수식을 완성할수도 있다.

여까지 이해가 되었는가???   

첫번째 if문은 x, y 파라미터가 각각 숫자타입으로 들어왔다면 

x, y가 같을떄는 0 을 반환 , x가 크다면 1를 반환 y가 크다면 -1을 반환한다는 얘기다

위와같이 만든 campare함수에 (숫자, 문자열) 을 집어 넣으면 오류 메세지가 나올것이다.. 맞지?

 

이를 이용해서 임의의 값을 주었을 때 console.log로 정렬되어 찍어낼수도 있겠다.

1
2
3
4
5
6
7
8
9
10
11
12
function compare(x: string | number, y: string | number) {
    if(typeof x === 'number' && && typeof y ==='number'){
    return x === y ? 0 : x > y ? 1 : -1;
    }
    if(typeof x === 'string' && && typeof y ==='string'){
    return x.localeCompare(y);
    }
    throw Error('not supported type');
}    
console.log([3,2,1].sort(compare));
 
console.log(['c','a','b'].sort(compare));

콘솔을 찍어내면

여기서 stirng.localeCompare() 메서드는 기준 문자열과 비교했을 때 비교 대상 문자열이 정렬상 전에 오는지, 

후에 오는지 혹은 같은 순서에 배치되는지를 알려주는 숫자를 리턴해준다.

console.log('a'.localeCompare('b')); // -1 
console.log('b'.localeCompare('a')); // 1 
console.log('b'.localeCompare('b')); // 0

(요기나게 쓸거같아서....ㅎㅎ)

 

이번엔 primitive 타입이 아닌 interface를 union type으로 적용했을때 보자

1
2
3
4
5
6
7
8
9
interface User {
    name: string;
}
interface Action {
    do() : void;
}
function process(v: User | Action) {
    if(typeof v === "")
}

별다를거 없어 보인다....그런데??

알아둬야할것이 인터페이스는 자바스크립트에서 존재하지 않는다!!! 즉?

primitive 타입밖에...typeof는 자바스크립트 문법이잖아..!!! 그럼 object 써주면되는거 아니야?

--> 그럼 둘이 타입이 구분이 되지않아...멍청아.

 

그럼 이렇게하면 되지 않아??

-->

function process(v: User | Action) {
	if (v.do) 이렇게 말이다....
}

User | Action 은 유니온 타입이기때문에( 합쳐 졌기때문에 ) v.do는 혼란이 온다.  그럴땐 이와같이 해결하는 방법이있다.

 

1
2
3
function process(v: User | Action) {
    if ((<Action>v).do) {
(<Action>v).do()
}
}
 

이렇게 타입을 구별 할수 있다. 근데 좀 지저분한데?? 매번 타입을 이렇게 지정하면....좀그래

---> 직접 타입가드를 만들어보자

 

1
2
3
4
5
6
7
8
9
10
function isAction(v: User | Action): v is Action {
    return (<Acton>v).do!== undefined;
}
 
function process(v: User | Action) {
    if (isAction(v)) {
        v.do()
    } else {
         console.log(v.name)
}

 실제 프로젝트에서 이렇게까지 쓰일진 모르겠지만 틈이보이면 바로 적용해봐야 겠다.

 

 

 

 

 

'JS > TypeScript' 카테고리의 다른 글

TypeScript) tsconfig.ts 설정하기  (0) 2019.08.31
TypeScript 클래스 (Class Type)  (0) 2019.08.29
TypeScript Enum  (0) 2019.08.29
TypeScript 함수형 타입(function Type)  (0) 2019.08.29
TypeScript 인터페이스(Interface)  (0) 2019.08.29