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

[타입스크립트 이해하기] 타입 계층도와 함께 기본타입 살펴보기

해갈 2023. 7. 6. 15:06

해당 게시글은

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

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

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

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

출처는 다음과 같습니다.

 

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

 

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

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

ts.winterlood.com

 

지난 시간에 배운 내용을 토대로

타입 계층도를 다시 한 번 살펴보며

여러가지 기본 타입들이 각각 왜 그런 특징을 갖는지

자세히 살펴보았습니다.

 

unknown 타입 (전체 집합)

unknown 타입은 타입 계층도의 최상단에 위치합니다.

따라서 unknown 타입 변수에는

모든 타입의 값을 할당할 수 있습니다.

바꿔 말하면,

모든 타입은 unknown 타입으로 업 캐스트할 수 있습니다.

let a: unknown = 1;                 // number -> unknown
let b: unknown = "hello";           // string -> unknown
let c: unknown = true;              // boolean -> unknown
let d: unknown = null;              // null -> unknown
let e: unknown = undefined;         // undefined -> unknown
let f: unknown = [];                // Array -> unknown
let g: unknown = {};                // Object -> unknown
let h: unknown = () => {};          // Function -> unknown

unknown 타입이 타입 계층도에서

가장 위에 위치한다는 뜻은 unknown 타입은

모든 타입의 슈퍼 타입이라는 뜻입니다.

그러므로 모든 타입은 unknown 타입의 부분집합입니다.

 

결국 unknown 타입은

모든 타입을 부분집합으로 갖는 타입스크립트 전체 집합입니다.

 

앞서 다운캐스트는 예외적인 경우가 아니면.

허용되지 않는다고 배웠습니다.

따라서 unknown 타입의 값은 any 를 제외한 어떤 타입의 변수도에도 할당할 수 없습니다.

let unknownValue: unknown;

let a: number = unknownValue;
// 오류 : unknown 타입은 number 타입에 할당할 수 없습니다.

never 타입 (공집합 타입)

never 타입은 타입 계층도에서 가장 아래에 위치합니다.

앞서 never 타입은 불가능, 모순을 의미하는 타입이라고 설명했습니다.

타입이 집합임을 이해한 지금,

never 타입을 다시 표현하자면

공집합을 뜻하는 타입입니다.

수학에서의 공집합은 아무것도 포함하지 않는 집합이라는 뜻입니다.

따라서 never 타입에 해당하는 값은

말 그대로 아무것도 없습니다.

따라서 다음과 같은 상황에 never 타입이 주로 사용됩니다.

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

errorFunc 함수는에러를 발생시킵니다.

따라서 이 함수는 정상적으로 종료되지 않습니다.

그러므로 어떤 값도 반환할 수 없습니다. 

만약 이 함수가 어떤 값을 반환한다면 그것은 불가능하며 모순입니다.

 

또 공집합은 모든 집합의 부분집합입니다.

그러므로 never 타입은 모든 타입의 서브 타입입니다.

따라서 never 타입은 모든 타입으로 업캐스팅할 수 있습니다.

let neverVar: never;

let a: number = neverVar;            // never -> number
let b: string = neverVar;            // never -> string
let c: boolean = neverVar;           // never -> boolean
let d: null = neverVar;              // never -> null
let e: undefined = neverVar;         // never -> undefined
let f: [] = neverVar;                // never -> Array
let g: {} = neverVar;                // never -> Object

 

반면, 그 어떤 타입도 never 타입으로 다운 캐스팅할 수 없습니다.

let a: never = 1;                 // number -> never ❌
let b: never = "hello";           // string -> never ❌
let c: never = true;              // boolean -> never ❌
let d: never = null;              // null -> never ❌
let e: never = undefined;         // undefined -> never ❌
let f: never = [];                // Array -> never ❌
let g: never = {};                // Object -> never ❌

void 타입

다음으로 살펴볼 타입은 void 타입입니다.

 

void 타입은 앞서 다음과 같이

아무것도 반환하지 않는 함수의 반환값 타입으로 주로 사용된다고 했습니다.

function noReturnFunc(): void {
  console.log("hi");
}

타입 계층도에서 void 타입을 찾아보면

void 타입은 undefined 타입의 슈퍼 타입임을 알 수 있습니다.

 

따라서 반환값을 void 로 선언한 함수에서 undefined 을 반환해도

오류가 발생하지 않습니다.

undefined 타입은 void 타입의 서브 타입이므로

업스캐팅이 가능하기 때문입니다.

function noReturnFuncA(): void {
  return undefined;
}

function noReturnFuncB(): void {
  return;
}

function noReturnFuncC(): void {}

 

void 타입의 서브 타입은 undefined 타입과 never 타입 밖에 없습니다.

따라서 void 타입에는 undefined, never 이외에

다른 타입의 값을 할당할 수 없습니다.

let voidVar: void;

voidVar = undefined; // undefined -> void (ok)

let neverVar: never;
voidVar = neverVar; // never -> void (ok)

any 타입 (치트키)

any 타입은 사실상 타입 계층도를 완전히 무시합니다.

any 는 일종의 치트키같은 타입입니다.

 

any 는 뭐든지 예외입니다.

모든 타입의 슈퍼 타입이 될 수도 있고,

모든 타입의 서브 타입이 될 수도 있습니다.

let anyValue: any;

let num: number = anyValue;   // any -> number (다운 캐스트)
let str: string = anyValue;   // any -> string (다운 캐스트)
let bool: boolean = anyValue; // any -> boolean (다운 캐스트)

anyValue = num;  // number -> any (업 캐스트)
anyValue = str;  // string -> any (업 캐스트)
anyValue = bool; // boolean -> any (업 캐스트)

 

각각 number, string, boolean 타입을 갖는 변수

num, str, bool 에 any 타입의 값을 할당합니다.

이는 any 타입이 각각 number, string, boolean 타입으로

다운 캐스트된다고 이해할 수 있습니다.

 

또 any 타입 변수 anyValue 에 num, str, bool 에

any 타입의 값을 할당합니다.

이는 number, string, boolean 타입이 모두 any 타입으로

업캐스트되는 것으로 이해할 수 있습니다.

 

이렇듯 any 타입은 모든 타입으로 다운캐스트할 수 있으며

또 모든 타입은 any 타입으로 업캐스트할 수 있습니다.