타입 스크립트에서 사용하는 타입 중에 void, never ,unknown, any 타입에 대해 알아보자.
이전 게시글에서는 원시타입 위주로 정리하였는데, 이번에는 그 외 타입들 (object 나 array 같은 것들은 다음 게시글에서 정리하고...)에 대해 알아보고자 한다.
Void
void 타입은 자바를 사용해본 사람은 알겠지만 보통 함수에서 반환 값이 없을 때 반환 타입을 표현하기 위해 사용된다.
물론 일반 타입 변수로 선언할 수 있으나, 해당 변수에는 undefined만 할당할 수 있기 때문에 사용을 안 한다.
(--strictNullchecks를 사용하지 않으면 null 역시 가능하나 일반적으로 해당 옵션을 사용하기 때문에 넘어가자.)
let unusable: void = undefined;
unusable = 'record' // error : 'string' 형식은 'void' 형식에 할당할 수 없습니다.
// 타입 명시
function warnUser(): void {
console.log("This is my warning message");
}
// 생략 시 자동으로 타입이 지정되나
// 보통 반환값이 없을때만 생략하고 반환값이 있으면 타입을 명시해준다.
function voidFunc() {
console.log("This is my warning message");
}
void 타입은 보통 함수에서만 사용하며, 반환 값이 없다는 건 바로 보이기 때문에 생략해 주는 경우가 많다.
Never
never 타입은 모든 타입에 할당 가능한 하위 타입이나, never타입에는 본인 외에 다른 타입이 할당될 수는 없다.
never 타입은 절대 발생할 수 없는 타입을 나타낸다.
그렇다면 도대체 Never 타입은 어디다 사용하는 걸까?
가장 흔한 예제로는 에러를 발생시킬 때 사용된다.
function fail(msg: string): never {
throw new Error(msg);
}
사용법에 대해 좀 더 찾아봐야겠지만 그 외에도 특정 타입 값을 할당받지 않도록 하거나, 매개변수의 제한을 건다거나 뭐 그런 곳들에 사용된다는데, 사실 많이 사용하는 타입은 아니라고 봐도 무방하다.
Unknown과 Any
두 타입을 같이 설명하는 이유는 두 타입 모드 타입을 지정하기 애매할 때 사용하기 때문이다.
우선 Any 타입부터 살펴보자면
any 타입은 모든 타입을 할당받을 수 있는 타입이다.
let str: any = 'anything';
str = 2;
str = [1, 2, 3];
하지만 모든 타입을 할당받는다는 의미는 의도치 않은 형 변환이나 다른 타입의 값이 대입되는 등 여러 사이드 이펙트를 발생시킬 수 있다는 의미이다.
그리고 해당 타입의 메서드를 사용할 때 "타입 표명(type-assertion)"을 사용해서 사용해야 하기 때문에 사용할 때 유의하여야 한다. (물론 억지로 사용해도 런타임에는 문제가 없다 타입 검사를 항상 만족하는 타입이기 때문에)
이제 Unknown 타입에 대해 알아보면
unknown 타입은 any처럼 모든 타입을 넣어도 상관없다라기보다는 "이 변수는 어떤 타입이 될지 모르니 네가 추론해줘"라는 의미와 같다. 좀 더 겸손한 의미? 랄까
let str: unknown = 'anything';
str = 2;
str = [1, 2, 3];
일단 모든 타입을 할당할 수 있다는 점은 any와 unknown 타입 둘 다 동일하나 분명한 차이점 역시 존재한다.
// any 타입 변수 할당
let str: any = 'anything';
let test: string = str;
// unkown 타입 변수 할당
let str2: unknown = 'unknown';
//let test2: string = str2; // error : 'unknown' 형식은 'string' 형식에 할당할 수 없습니다.
let test2: string = (str2 as string);
str = str2;
위 예시처럼 any 타입은 다른 타입의 변수에도 할당이 가능하다.
반면에 unknown 타입의 경우 any 타입을 제외한 나머지 타입 변수에는 타입 표명을 하지 않는 이상 할당이 불가능하다.
(unknown에서 타입 표명을 사용하거나 아니면 typeof나 그 외 타입을 확인하는 방법이 있으면 할당이 가능하다.)
그 외에도 unknown 타입의 변수에는 프로퍼티 접근도 못하고, 인스턴스 생성 역시 할 수 없다 항상 타입을 확인해야 하기 때문에 반면에 any타입은 굳이 타입 확인을 하지 않는다.
이러한 둘의 차이점만 보더라도 any는 왜 typescript를 사용하나 싶을 정도로 기본 javascript 변수처럼 자유도가 높은 반면 unknown 타입은 any 타입에 비해 자유도가 많이 떨어진다.
그래서 굳이 따지자면 안전성 측면에서는 unknown 타입이 높은 편인데,
개인적인 생각으로는 진짜 특수한 상황이 아닌 이상 unknown 타입과 any 타입은 사용하지 않는 게 맞지 않을까 싶다.
참고: https://www.typescriptlang.org/ko/docs/handbook/2/everyday-types.html
참고: https://www.typescriptlang.org/docs/handbook/2/narrowing.html
댓글