기본 타입간의 호환성

특정 타입을 다른타입으로 취급해도 괜찮은지를 판단한다.

타입계층도

객체타입간의 호환성

어떠한 객체타입이 있을때 이 타입을 다른 객체타입으로 취급해도 괜찮은가?

객체타입은 프로퍼티를 기준으로 관계를 갖는다. 객체에서는 Dog타입같은 추가 프로퍼티가 있는 타입이 슈퍼타입이 되지않고, animal 같은 최소한의 프로퍼티들만으로 이루어진 타입이 슈퍼타입이 된다.

// 슈퍼타입
type Animal = {
	name: string;
	color: string
}
// 서브타입
type Dog = {
	name: string;
	color: string;
	breed: string;
}
let animal = Animal = {
	name: 'cat',
	color: 'black'
}
let dog : Dog = {
	name: 'hi',
	color: 'white',
	breed: 'jindo'
}

animal = dog; // 업캐스팅가능
dog = animal // 다운캐스팅이기 때문에 에러발생

초과 프로퍼티 검사

초과 프로퍼티 검사란 변수를 선언할 때 객체리터럴을 직접 할당하는 경우에만 발동하는 엄격한 타입 검사이다. 초기화 시에는 실제 프로퍼티에 정의해놓지 않은 프로퍼티를 작성 할 수 없다.

// 재할당은 가능하나 (dog변수는 breed 프로퍼티가 있는데도 animal 타입에 할당할 수 있다)
animal = dog;

// 직접 초기화 시에는 안된다.
let animal2 :Animal = {
	name: 'hi',
	color: 'white',
	breed: 'jindo' // Error: 'breed' does not exist in type 'Animal'
}

왜 초과프로퍼티 검사를 할까?

타입스크립트는 구조적 타입시스템을 사용한다. 즉, 타입 이름이 같을 필요는 없고, 필요한 속성만 정확히 들어있으면 타입이 일치하는 것으로 간주된다.

type Animal = {
    name: string;
    color: string;
};

type Car = {
    name: string;
    color: string;
};

let animal: Animal = {
    name: '기린',
    color: '노랑'
};

let car: Car = {
    name: '모닝',
    color: '파랑'
};

// Animal, Car 타입 이름이 다르지만 속성이 모두 일치하기 때문에 호환가능한 타입으로 간주된다.
animal = car;
car = animal;

하지만 객체리터럴은 개발자가 직접 만든 값이기 때문에, 타입스크립트는 이를 실수가능성이 높은 코드로 보고 더 엄격하게 검사한다.

// 타입에 정의되지 않은 breed를 넣었으니 에러가 난다
let animal2 :Animal = {
	name: 'hi',
	color: 'white',
	breed: 'jindo' // Error: 'breed' does not exist in type 'Animal'
}

반면에, 이미 변수로 선언된 객체를 할당한 경우에는 초과프로퍼티가 있어도 필요한 속성만 있으면 에러가 발생하지 않는다. (타입에 정의된 필수 속성은 반드시 포함되어 있어야 함)

let dog : Dog = {
	name: 'hi',
	color: 'white',
	**breed: 'jindo' // Animal타입에 정의하지않은 breed라는 초과 프로퍼티가 있는데도 가능**
}
// 가능
**animal = dog;**

let dog2 : Dog = {
	name2: 'hi',
	color2: 'white',
	breed2: 'jindo'
}
animal = dog2;  // 불가 Animal 타입에 정의한 name,color 프로퍼티가 없음

매개변수로 전달할때도 마찬가지

// 매개변수로 받을 dog 의 타입을 Animal로 지정해주었다.
function func(dog :Animal) {}

func({
	name2: 'hi',
	color2: 'white',
	breed2: 'jindo' // 불가
})

func(dog2) // 변수를 통해 전달하면 가능