let num1: number = 10;
let num2: 10 = 10;
num1 = num2; // ✅ OK
num2 = num1; // ❌ NO객체 타입간의 호환성도 동일한 기준으로 판단함. 모든 객체 타입은 각각 다른 객체 타입들과 슈퍼-서브타입 관계를 가짐. 따라서 업캐스팅은 허용하고 다운캐스팅은 허용하지 않음.
type Animal = {
name: string;
color: string;
};
type Dog = {
name: string;
color: string;
breed: string;
};
let animal: Animal = {
name: "기린",
color: "yellow",
};
let dog: Dog = {
name: "돌돌이",
color: "brown",
breed: "진도",
};
animal = dog; // ✅ OK
dog = animal; // ❌ NO→ Animal 타입의 변수 animal에 Dog 타입의 변수 dog를 할당하는 것은 가능
→ 그러나 반대로 dog 변수에 animal 변수의 값을 할당하는 것은 불가능
→ Animal 타입이 Dog 타입의 슈퍼타입이기 때문
TS는 프로퍼티 기준으로 타입을 정의하는 구조적 타입 시스템을 따름.
- Animal 타입은 name과 color 프로퍼티를 갖는 모든 객체들을 포함하는 집합으로 볼 수 있음
- Dog 타입은 name과 color 거기에 추가로 breed 프로퍼티를 갖는 모든 객체를 포함하는 집합으로 볼 수 있음
그렇기 때문에 어떤 객체가 Dog 타입에 포함되면 무조건 Animal 타입에도 포함됨. 그러나 반대로 Animal 타입에 포함되는 모든 객체가 Dog 타입에 포함되는 것은 아님. 따라서 Animal 은 Dog의 슈퍼타입임
다음 예제도 본다면
type Book = {
name: string;
price: number;
};
type ProgrammingBook = {
name: string;
price: number;
skill: string;
};
let book: Book;
let programmingBook: ProgrammingBook = {
name: "한 입 크기로 잘라먹는 리액트",
price: 33000,
skill: "reactjs",
};
book = programmingBook; // ✅ OK
programmingBook = book; // ❌ NO이때 만약 새로운 변수를 만들고 다음과 같이 초기값을 설정하면 오류 발생
type Book = {
name: string;
price: number;
};
type ProgrammingBook = {
name: string;
price: number;
skill: string;
};
(...)
let book2: Book = { // 오류 발생
name: "한 입 크기로 잘라먹는 리액트",
price: 33000,
skill: "reactjs",
};→ Book 타입으로 정의된 변수 ProgrammingBook 타입으로 보이는 초기값을 설정함. 그 결과 오류가 발생함…
Why? 초과 프로퍼티 검사가 발동해서 그럼
- 초과 프로퍼티 검사: 변수를 객체 리터럴로 초기화할 때 발동하는 TS의 특수한 기능
- 타입에 정의된 프로퍼티 외의 다른 초과된 프로퍼티를 갖는 객체를 변수에 할당할 수 없도록 막음
→ 따라서 위 코드는 Book 타입에 정의되지 않은 객체를 할당하려고 했기에 오류 발생
이런 초과 프로퍼티 검사는 단순이 변수를 초기화 할 때 객체 리터럴을 사용하지만 않으면 발생하지 않음. 따라서 다음과 같이 값을 별도의 다른 변수에 보관한 다음 변수 값을 초기화 값으로 사용하면 발생하지 않음
(...)
let book3: Book = programmingBook; // 앞서 만들어둔 변수초과 프로퍼티 검사는 함수의 매개변수에도 동일하게 발생
function func(book: Book) {}
func({ // 오류 발생
name: "한 입 크기로 잘라먹는 리액트",
price: 33000,
skill: "reactjs",
});함수의 매개변수에 인수로 값을 전달하는 과정도 변수를 초기화하는 과정과 동일함. 따라서 초과 프로퍼티 검사가 발동하게 됨. 이때에도 역시 검사를 피하고 싶다면 다음과 같이 변수에 미리 값을 담아둔 다음 변수값을 인수로 전달
func(programmingBook);