TypeScript/한 입 크기로 잘라먹는 타입스크립트

[타입스크립트 기본] void 와 never

해갈 2023. 7. 6. 13:20

해당 게시글은

강의 사이트, 인프런에서 이정환님이 진행하시는

'한 입 크기로 잘라먹는 타입스크립트' 

들어보며 블로그를 작성하려고 합니다.

다음 게시글 내용은 해당 강의에 핸드북의 내용으로

출처는 다음과 같습니다.

 

https://ts.winterlood.com/7250edd7-a3fd-4662-b756-f11f927c73f2

 

타입스크립트를 소개합니다 - 타입스크립트 개론

한 입 크기로 잘라먹는 타입스크립트

ts.winterlood.com

 

chapter7.ts 에서 실습을 진행했습니다.

 

void

void 타입은 아무런 값도 없음을 의미하는 타입입니다.

보통은 다음과 같이 아무런 값도 반환하지 않는 함수의 반환값 타입을 정의할 때 사용합니다.

function func2(): void {
  console.log("hello");
}

 

물론 다음과 같이

변수의 타입으로도 당연히 void 타입을 지정할 수 있습니다.

그러나 void 타입의 변수에는

undefined 이외의 다른 타입의 값을 담을 수 없습니다.

그 이유는 void 타입이 undefined 타입을 포함하는 타입이기 때문인데

이에 대해서는 3섹션에서 자세히 살펴볼 예정입니다.

let a: void;
a = undefined;

 

그런데 만약 이때 tsconfig.json 에

엄격한 null 검사(strictNullChecks) 옵션을 해제(False) 로 설정하면

특별히 이때에는 void 타입의 변수에 null 값도 담을 수 있게 됩니다.

// "strictNullChecks: false" 일 경우
let a: void;
a = undefined;
a = null;

 

그런데 한 가지 이상한 점이 있습니다.

자바스크립트에는 이미 아무런 값도 없음을 의미하는

null 과 undefined 가 존재하는데,

왜 void 타입이 추가로 필요한 걸까요?

그 이유는

함수의 반환값 타입을 undefined 으로 설정해보면 알 수 있습니다.

function func2(): undefined { // 오류 발생!
  console.log("hello");
}

위와 같이 반환값 타입을 undefined 로 설정하면

함수가 진짜 undefined 를 반환해야 합니다.

function func2(): undefined {
  console.log("hello");
  return undefined;
}

 

null 타입으로 정의해도 동일합니다.

진짜 null 값을 반환해야 합니다.

function func2(): null {
  console.log("hello");
  return null;
}

 

따라서 return 문 자체가 없는 함수의 반환값 타입을 정의해야 할 때에는

다음과 같이 void 타입을 이용해야 합니다.

function func2(): void { // 오류 발생!
  console.log("hello");
}

never 타입

never 타입은 불가능을 의미하는 타입입니다.

보통 다음과 같이 함수가 어떤한 값도 반환할 수 없는 상황일 때

해당 함수의 반환값 타입을 정의할 때 사용됩니다.

function func3(): never {
  while (true) {}
}

함수 func3 은 무한 루프를 돌기 때문에

아무런 값도 반환할 수 없습니다.

엄밀히 말하면, 이 함수는 영원히 종료될 수 없기 때문에

뭔가를 반환한다는 것 자체가 '불가능' 합니다.

이렇게 불가능한 값의 타입을 정의할 때,

never 타입을 사용합니다.

 

무한 루프 외에도 다음과 같이 의도적으로 오류를 발생시키는 함수도

never 타입으로 반환값 타입을 정의할 수 있습니다.

function func4(): never {
  throw new Error();
}

 

변수의 타입을 never 로 정의하면 any 를 포함해

그 어떠한 값도 이 변수에 담을 수 없게 됩니다.

let anyVar: any;
(...)

let a: never;
a = 1;
a = null;
a = undefined;
a = anyVar;