TypeScript 타입 심화

박철연·2022년 3월 2일
2

TypeScript 묶음

목록 보기
3/6
post-thumbnail

자바스크립트를 공부하다 보면, 자연스럽게 타입스크립트(TypeScript)를 자주 접하게 됩니다. 타입스크립트 개념을 배우는 과정에서, 개별 시리즈에 게시물을 포스팅하는 방식으로 타입스크립트 공부를 정리해보고자 합니다.

저번 글에서 타입스크립트의 기본적인 타이핑에 대해 알아보았는데요, 이번엔 좀 더 심화된 내용들을 공부해 봤습니다.

타입 확정하기

유니언 타입의 조작

저번 글에서 만들어 본 것과 비슷한 함수입니다. 인자로는 유니언 타입을 사용해서 숫자와 문자열 모두 받을 수 있게 작성했습니다.

그런데 에러가 뜨는군요. 에러의 자세한 내용을 알아보겠습니다.

'+' 연산자를 string | number에 적용할 수 없다고 합니다.

저번 글에서 이해한 것과 같이, 유니언 타입은 그 자체로 하나의 타입으로 만들어집니다. 따라서 string | number는 number와는 다른 타입이죠.

그래서 유니언 타입은 일반적으로 조작하지 못하게 되어 있습니다. 이를 해결하기 위해서는 narrow와 assert의 개념을 알아야 합니다.

Type Narrowing

narrow는 영어로 '좁은'의 의미를 가지고 있죠. 말 그대로, 타입 지정의 범위를 좁혀서 하나의 타입으로 받아들여지게끔 하는 것입니다.

좀 전에 예시를 든 함수를 그대로 가져와서, if문을 사용해주었습니다.

x의 타입이 숫자일 때와 문자열일 때를 나누어서 함수를 작성했습니다. 보시다시피 x의 타입이 뭐가 되었든 1을 더하게 될 것입니다.

이러면 아까 유니언 타입때문에 발생하던 오류가 깔끔히 해결된 것을 볼 수 있습니다.

한 가지 알아두면 좋은 것은, 일반적인 if문과는 다르게 마지막에 else 절을 반드시 추가해주어야 합니다.

이는 return을 하지 않는 조건문이 있으면 나중에 오류를 발생시킬 가능성이 있기 때문입니다.

다만 tsconfig.json에서 '"noImplicitReturns": false'를 추가해서 이런 상황을 방지하는 것도 가능합니다.

Type Assertion

assertion은 as라는 키워드를 사용해서 엄격한 타입 지정을 한 번 해제하는 기능입니다. 바로 코드를 한번 만들어 보겠습니다.

함수의 인자는 여전히 유니언 타입이지만, x를 as number라는 키워드를 써서 숫자로 간주합니다.

as는 어디까지나 일회성으로 타입 지정을 바꾸는 것이라, 실제 들어온 데이터(여기서는 인자)의 타입을 직접 바꾸지 않습니다.

즉, 위에 작성한 코드가 문제없이 실행되려면 실제로 인자에 숫자만 들어올 것이라는 확신이 필요합니다.

따라서 코드를 작성할 때에는 앞서 다룬 narrowing이 권장됩니다. 더욱 보수적인 방법이기 때문이에요.

assertion은 타입 에러의 원인을 알 수 없을 때 임시로 타입 체크를 벗어나거나, 내가 다루는 데이터 타입을 확실하게 알고 있는데 타입 에러가 발생했을 때 사용하면 쏠쏠할 것 같습니다.

타입 별칭 (Type Aliases)

타입 별칭을 왜 쓰나요?

타입 지정을 하나로 못 박기 힘들 때는 유니언 타입을 쓰면 됩니다. 그런데 변수에 지정해야 할 타입의 갯수가 상당히 많다면 어떨까요?

number도 되고, boolean도 되고, string, null 등등 다 가능하다고 생각해 봅시다.

그러면 타입 지정과 관련된 코드가 상당히 길어지고, 가독성을 떨어뜨리는 데 한 몫 하게 되지 않을까요?

자바스크립트에서 변수에 데이터를 담는 것 처럼, 타입 지정도 그릇에 담아줄 수 있습니다. 그 그릇이 바로 타입 별칭(Type Aliases)입니다.

타입 별칭 만들어보기

타입 별칭을 만들 때는 키워드 type을 사용한 문법을 적용합니다. 다음 예시를 한 번 살펴보세요.

Things라는 타입 별칭을 만들어 준 예시입니다. 이런 식으로 마치 변수 쓰듯이 타입 별칭을 만들어 두면 코드도 간소화되고, 수정도 쉽겠죠?

물론 일반 변수들과 구분을 하기 위해 작명에는 신경써줘야 합니다.

타입 별칭은 객체 데이터에도 얼마든지 적용 가능합니다.

위 쪽의 코드가 타입 별칭 없이 만든 객체(teacher1)이고, 아래가 타입 별칭을 적용한 객체(teacher2)입니다.

타입 별칭과 함수

타입스크립트에서는 함수 역시 타입 지정이 가능합니다. 함수에 들어갈 인자도 타입 지정을 하고, 함수의 결과값도 타입 지정을 하죠.

따라서 똑같은 맥락으로 함수를 사용할 때에도 타입 별칭을 쓸 수 있습니다.

데이터의 타입 지정과 비슷하죠? NumFunc라는 함수 타입을 만들었습니다.

이 NumFunc라는 타입은 인자로 숫자 두 개(x, y)를 받고 결과도 숫자로 반환합니다.

이를 바탕으로 두 인자를 서로 곱한 값을 반환하는 func1을 만든 예시입니다.

객체의 속성으로 존재하는 메서드들도 당연히 함수이기 때문에 위와 같은 방법으로 타입 별칭을 활용할 수 있겠습니다.

Readonly

타입을 잠그는 방법, readonly

자바스크립트에서 원시 자료형과 객체 자료형은 메모리에 값을 저장하는 방식이 다릅니다.

원시 자료형은 메모리 주소에 직접 그 값을 기록하지만, 객체 자료형은 값을 다음 메모리를 참조하게 됩니다.

그래서 값의 재할당이 불가능한 const로 변수를 만들어도, 원시 자료형이 아닌 객체 자료형은 안의 속성을 바꾸는 것이 가능합니다.

이거 왠지... 타입스크립트가 들으면 호통칠 것 같은 내용 아닌가요? const로 기껏 변수를 만들었더니, 객체 안의 내용은 슉슉 바꾼다니...

그래서 readonly 문법을 통해, 객체형 변수 안의 속성을 제어하는 것도 방지할 수 있습니다.

readonly 사용법

Food라는 타입에 readonly를 사용해서 name에 문자열만 들어갈 수 있게 코드를 작성했습니다.

아래쪽에 lunch.name을 'Salad'로 바꾸려고 하니 에러가 나는군요. 에러를 한 번 살펴 보겠습니다.

읽기 전용 속성이라서 할당이 안된다고 하죠? readonly를 쓰면 이렇게 객체의 속성이 임의로 조작되는 것을 막을 수 있습니다.

타입 더 파보기

속성을 선택사항으로 정하기

방금 객체의 속성을 readonly를 써서 읽기 전용으로 만들어 보았습니다.

그런데 객체 속성의 타입을 지정할 때, 굳이 해당 속성을 작성하지 않아도 타입스크립트가 허용하게끔 하는 방법도 있습니다.

다음 코드를 한 번 보세요.

속성 중에 isMarried라는 속성은 boolean으로 타입 지정을 했습니다. 그런데 뒤에 물음표가 붙어 있습니다.

이렇게 물음표를 붙이면, 해당 속성은 선택 사항이 되어서 작성하지 않아도 에러를 일으키지 않습니다. 실제로 John이라는 변수는 Person 타입에 속하지만 isMarried 속성을 생략했죠.

한 가지 알고 가면 좋은 점은, 속성에 물음표를 붙이게 되면 실제로 선택 사항이 된다기 보다는 해당 속성의 타입으로 undefined도 허용한다는 것입니다.

타입의 유니언 타입

그냥 일반 데이터 타입만 유니언 타입이 가능한 것은 아닙니다. 타입과 타입도 유니언 타입이 됩니다.

Person 타입에 커서를 올려보면 string | number로 나오게 됩니다. 이런 식으로 타입과 타입을 합쳐 유니언 타입을 만드는 것도 가능합니다.

타입은 재지정 불가

타입은 재지정이 불가능합니다.

커서를 올려보면 Name 식별자가 중복되었다고 합니다. 애초에 같은 식별자를 가진 타입을 재정의할 수 없기 때문에 그런 에러 메시지가 뜨는 것입니다.

Type 키워드는 재정의가 불가능하지만, 나중에 다뤄볼 interface 키워드는 가능합니다.

profile
Frontend Developer

0개의 댓글