Skip to content

Void / Never

TypeScript에서 voidnever는 주로 함수의 반환 타입을 표현할 때 사용한다.
둘 다 “일반적인 값을 반환하지 않는다”는 공통점이 있지만, 의미는 다르다.

  • void: 함수가 반환값을 사용하지 않음을 표현
  • never: 함수가 정상적으로 끝나지 않음을 표현

Void

void는 함수의 반환값을 사용하지 않을 때 사용하는 타입이다.
주로 console.log()처럼 어떤 동작은 수행하지만, 호출한 쪽에서 결과값을 기대하지 않는 함수에 사용한다.

ts
function func1(): void {
  console.log('hello');
}
ts
// ex.
function logMessage(message: string): void {
  console.log(message);
}

logMessage('Hello TypeScript');

위 함수는 메시지를 출력하지만, 별도의 값을 return하지 않는다.
따라서 반환 타입을 void로 지정할 수 있다.


void 함수에서 return 사용하기

void 함수에서는 값을 반환하지 않는 return은 사용할 수 있다.

ts
function stop(): void {
  return;
}

하지만 특정 값을 반환하면 오류가 발생한다.

ts
function getMessage(): void {
  return 'hello'; // Error
}

void는 함수의 반환값을 사용하지 않는다는 의미이기 때문이다.


예시: 이벤트 핸들러

void는 이벤트 핸들러나 콜백 함수에서 자주 사용된다.

ts
function handleClick(): void {
  console.log('button clicked');
}

React 같은 환경에서도 클릭 이벤트처럼 무언가를 실행만 하고 값을 반환하지 않는 함수에 자주 등장한다.

ts
const handleSubmit = (): void => {
  console.log('submit');
};

🤔 왜 undefinednull이 아니라 void를 사용할까?

JavaScript에서 함수가 아무 값도 반환하지 않으면 기본적으로 undefined가 반환된다.

ts
function logMessage(): void {
  console.log('hello');
}

const result = logMessage();

console.log(result); // undefined

그렇다면 반환 타입을 undefined로 쓰면 될 것 같지만, voidundefined는 의미가 다르다.

void는 “이 함수의 반환값을 사용하지 않는다”는 의도를 표현한다.
반면 undefined는 실제로 undefined를 반환해야 한다는 제약을 건다.

ts
// void: return 생략 가능
function logA(): void {
  console.log('hello');
}

// void: return undefined도 가능
function logB(): void {
  console.log('hello');
  return undefined;
}

// undefined: 반드시 undefined를 반환해야 함
function logC(): undefined {
  console.log('hello');
  return undefined;
}

// null: 반드시 null을 반환해야 함
function logD(): null {
  console.log('hello');
  return null;
}

즉, undefinednull은 특정 값을 반환하는 타입이고,
void는 반환값을 기대하지 않는 함수의 타입을 표현할 때 사용한다.

Never

never는 함수가 정상적으로 끝나지 않을 때 사용하는 타입이다.
즉, 함수가 값을 반환하지 않을 뿐만 아니라 함수 실행이 끝까지 도달하지 않는 경우를 의미한다.

대표적인 경우는 다음과 같다.

  • 에러를 던지는 함수
  • 무한 루프 함수
  • 도달할 수 없는 코드

에러를 던지는 함수

ts
function throwError(message: string): never {
  throw new Error(message);
}

이 함수는 throw를 통해 에러를 발생시키기 때문에 값을 반환하지 않고, 함수 실행도 정상적으로 끝나지 않는다.
그래서 반환 타입이 never가 된다.


무한 루프 함수

ts
function infiniteLoop(): never {
  while (true) {
    console.log('running...');
  }
}

이 함수는 무한히 반복되기 때문에 정상적으로 종료되지 않는다.
따라서 반환 타입을 never로 지정할 수 있다.


🧩 Void와 Never의 차이

voidnever는 모두 일반적인 값을 반환하지 않지만, 함수가 끝나는 방식이 다르다.

타입의미함수 종료 여부예시
void반환값을 사용하지 않음정상 종료 가능console.log()
never정상적으로 끝나지 않음정상 종료 불가throw, 무한 루프
ts
function log(): void {
  console.log('log');
}

function fail(): never {
  throw new Error('fail');
}

log()는 값을 반환하지 않지만 함수 실행은 정상적으로 끝난다.
반면 fail()은 에러를 던지기 때문에 함수 실행이 정상적으로 끝나지 않는다.