내일배움캠프

230727 타입스크립트 never 타입

Neda 2023. 7. 27. 19:36

230727 타입스크립트 never 타입

타입스크립트에는 숫자에서의 0이나 값에서의 null처럼 없는 타입을 정의하는 키워드 never가 있다

음 봤을 때는 뭔가 직관으로 이해가 가지 않았다. 예외를 처리? 아무것도 없는 타입? 절대 반환하지 않는 함수는 뭐지?

그러다 타입을 그냥 집합이라 생각하는 순간 공집합이라는 말이 쉽게 이해가 됐다

 

never 타입

never 타입에는 any타입을 포함하여 다른 모든 타입을 할당할 수 없다.

또한 never 타입은 모든 타입의 서브 타입이다

이는 공집합에 집합이 있을 수 없고, 모든 집합이 공집합을 포함하는 일반적인 개념과 같다.

 

never 가 사용되는 대표적인 경우는 2가지는 아래와 같다

  • 항상 예외를 발생시킬 때
  • 절대 반환하지 않는 함수의 반환 유형일 때

 

never 타입 변수

never타입 변수에는 never 타입이 아닌 어느 타입도 할당할 수 없다

never 타입 인자를 가지는 함수

마찬가지로 never 타입 인자를 가지는 함수에는 never 타입이 아닌 다른 모든 타입은 통과할 수 없다

never 타입은 공집합

never 타입은 공집합으로 볼 수 있다. 
다른 타입과 union(|, 합집합)을 하면 해당 타입이 그대로 나오게 된다.

반대로 다른 타입 간에 intersection(&, 교집합)을 하면 교집합이 없기 때문에 never 타입이 된다.

 

조건문을 통해 never 타입으로 좁히기(narrowing)

타입스크립트에서는 타입을 평가할 때 조건문을 통해 범위를 좁힐 수 있다

예를 들어 유니온을 통해 string 타입과 null 타입을 가질 수 있는 값을 value!==null을 통해 null 타입이 아님을 보장할 수 있다

type Title = string | null;
const title:Title = '';
if(title!==null){
  title // null 타입이 아니므로 항상 string임을 보장
}

 

이러한 방식으로 타입을 계속 좁혀 나가면 어느 타입도 남지 않게 된다. 그때의 타입이 never 타입이다.

switch문을 사용해 범위 좁히기

interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

type Shape = Circle | Square;

function getArea(shape: Shape) {
  switch (shape.kind) {  // Circle | Square
    case "circle":  // Circle 타입일 경우
      return Math.PI * shape.radius ** 2;
    case "square": // Square 타입일 경우
      return shape.sideLength ** 2;
    default: // 비교 가능한 모든 타입을 비교 했으므로 never타입
      const _exhaustiveCheck: never = shape;
      return _exhaustiveCheck;
  }
}

 

if else문을 사용해 범위 좁히기

function getArea(shape: Shape) {
  if(shape.kind ==='circle') {
    shape
  } else if (shape.kind === 'square'){
    shape
  } else {
    shape
  }
}

 

 

에러 처리를 위한 함수 

위의 코드에서 getArea의 default 문에서 never 타입의 예외가 발생 했을 때
에러를 발생시키는 함수를 직접 만들어 사용할 때 never 타입을 인자로 사용할 수 있다

function handleWrongType(x: never): never {
  throw new Error('잘못된 타입입니다')
}

function getArea(shape: Shape) {
  switch (shape.kind) {  // Circle | Square
    case "circle":  // Circle 타입일 경우
      return Math.PI * shape.radius ** 2;
    case "square": // Square 타입일 경우
      return shape.sideLength ** 2;
    default: // 비교 가능한 모든 타입을 비교 했으므로 never타입
      const _exhaustiveCheck: never = shape;
      handleWrongType(shape)
  }
}

 

 


 

Handbook - Basic Types

Step two in learning TypeScript: The basic types.

www.typescriptlang.org

 

타입스크립트의 Never 타입 완벽 가이드

타입스크립트의 never 타입은 다른 타입만큼 흔하게 사용되거나 피할 수 없는 것이 아니기 때문에 충분히 논의되고 있지 않다. 타입스크립트 초보자는 조건부 타입 같은 고급 타입을 처리하거나

ui.toast.com

 

타입스크립트 타입 never 에 대해 자세히 알아보자

Table of Contents never란 무엇인가 never가 무엇이고 왜 만들어졌는지 이해하기 위해서는, 먼저 타입시스템에서 타입이 무엇을 의미하는지 이해해야 한다. 타입은 가능한 값의 집합을 의미한다. 예를

yceffort.kr