1.사전 지식

타입스크립트의 호환을 이해하기 위해서

  • 부모타입=슈퍼타입=상위타입
  • 자식타입=서브타입=하위타입
  • 업캐스팅 : 서브타입을 슈퍼타입 값으로 취급한다. 즉, 작은놈을 큰놈에 집어넣음
  • 다운캐스팅: 슈퍼타입을 서브타입으로 취급한다. 큰놈을 작은놈에 집어넣음

집합의 개념으로 생각 해 보면 업캐스팅은 대부분의 경우 가능하지만 다운캐스팅은 불가한 경우가 많다.

 

let num1:number = 10 //넘버타입
let num2:20 = 20 //넘버 리터럴타입

① num1 = num2 //가능
② num2 = num1 //오류

 

(A) = (B) 일 때 B를 A로 취급한다, B를 A에 집어 넣는다 라고 생각하면 이해가 쉽다.

 

넘버타입은 넘버리터럴타입보다 집합범위가 넓기때문에 ①은 가능, ②는 불가능하다.

 

 

2.특이한 놈들

2-1) unknown 타입

  • 타입 계층 최상단에 있다.
  • 모든 타입의 슈퍼타입(부모타입)
  • 모든 타입은 unknown 으로 업캐스팅 가능 / unknown 타입의 값은 어떤 타입의 변수에도 할당 불가능
  • 다만 any타입에는 할당 가능하다.
 let num:number;
 let Un:unknown;

 num = Un // 이건 안 되고

 let anyVar:any;
 anyVar = Un //이건 된다

 

2-2) any 타입

  • 타입 계층도를 무시하며 자유롭게 업캐스팅, 다운캐스팅이 가능하다.
  • 모든 타입의 슈퍼타입이 될 수도, 서브타입이 될 수도 있다.
  • 그렇기때문에 any타입을 쓰는 것은 타입스크립트를 쓰지 않는것이나 다를 게 없어 주의가 필요

 

2-3) never 타입

  • 타입 계층 최하단에 있다.
  • 공집합이기때문에 어떤 타입도 다운캐스팅할 수 없다.(any 포함)
  • 모든 타입의 서브타입
  • 어떤 타입으로든 업캐스팅 가능하다.

 

2_4) void 타입

  • void의 서브타입으로는 undefined와 never가 있다.
  • 반환값이 void인 함수에서는 undefined를 반환해도 된다.
  • void타입의 변수에 들어갈 수 있는 타입은 undefined와 never뿐이다.

 

 

3.객체 호환

객체 호환 역시 "포함"의 개념으로 이해하면 쉽다.

type Book = {
    name:string;
    price:number;
}

type CookBook = {
    name:string;
    price:number;
    skill:string
}

let book1:Book = {
    name:"일반책",
    price:"1000"
}

let book2:CookBook={
    name:"요리책"
    price:2000,
    skill:"한식"
}

book1=book2 // 가능
book2=book1 // 오류

 

언뜻 보면 더 많은 프로퍼티를 갖고있는 CookBook이 슈퍼타입으로 보일 수 있겠다.

하지만 Book타입은 name과 price, 두 가지 프로퍼티만 갖고있으면 되고

CookBook타입은 name과 price에 이어 skill 프로퍼티까지 갖고있어야 하기 때문에

Book타입보다 CookBook타입으로 정의하는게 더 까다롭다고 볼 수 있다.

 

결론 : 객체 타입에서는 프로퍼티 갯수가 적을수록 슈퍼타입이다.

 

초과 프로퍼티

  • 객체 리터럴로 초기화할 때 실행되는 타입스크립트 문법
  • 타입에 정의된 프로퍼티 외 다른 초과된 프로퍼티를 갖는 객체를 변수에 할당하지 못하게 한다.
type Book = {
    name:string;
    price:number;
}

type CookBook={
    name:string;
    price:number;
    skill:string
}

let sellbook:Book={
    name:"요리책",
    price:22000,
    skill:"양식"
}

 

객체 sellbook의 타입은 name과 price만을 갖는 Book타입으로 정의했지만 

정작 초기값 설정은 skill프로퍼티까지 갖고있는 CookBook 타입으로 설정해서 오류 발생

 

  • 초과프로퍼티 오류를 피하기 위해서
let sellCookBook:CookBook = {
    name:"요리책",
    price:22000,
    skill:"양식"
}

let sellBook:Book = sellCookBook

 

이처럼 객체 리터럴 타입으로 초기값을 설정하지 않고,

변수에 담아 전달하면 초과프로퍼티를 피할 수 있다.

 

+ Recent posts