타입 호환성은 어떤 타입을 다른 타입으로 취급해도 되는지 판단하는 것이고 정적 타입 언어의 가장 중요한 역할은 타입 호환성을 통해 컴파일 타임에 호환되지 않는 타입을 찾아내는 것이다.
functuon func1(a: number, b: number | strung) { const v1: number | string = a; // 숫자는 number | string 타입에 할당 가능 const v2: number = b; // number | string 타입은 숫자에 할당 불가능
숫자와 문자열 타입은 서로 포함 관계에 있지 않기 때문에 서로 할당 가능하지 않지만 숫자의 집합은 number | string 값의 집합에 포함되기 때문에 할당가능하다.
interface Person { name: string; age: number; } interface Product { name: string; age: number; } const person: Person = { name: 'mike', age; 23 }; const product: Product = person; // 이름은 다르지만 내부 구조가 같기 떄문에 서로 할당 가능
타입스크립트는 값 자체의 타입보다는 값이 가진 내부 구조에 기반해서 타입 호환성을 검사하고 이를 덕 타이핑(duck typing) 또는 구조적 타이핑(structrural typing)이라 부른다.
interface Person { name: string; age?: number; } interface Product { name: string; age: number; } const person: Person = { name: 'mike', } const product: Product = person; // 타입 에러
age가 선택 속성이면 Person 값의 집합이 Product 값의 집합보다 커지기 때문에 Person은 Product에 할당 가능하지 않다.
추가 속성이 있으면 값의 집합은 작아지고 반대로 유니온 타입이 있으면 값의 집합은 더 커진다.
interface Person { name: string; age: number; gender: string; } interface Product { name: string; age: number | string; }
Person의 집합이 Product의 집합에 포함되기 때문에 할당 가능하다.
tpye F1 = (a: number, b: string) => number; tpye F2 = (a: number) => number; tpye F3 = (a: number) => number | string; let f1: F1 = (a, b) => 1; let f2: F2 = a => 1; let f3: F3 = a => 1; f1 = f2; f2 = f1; // 타입에러 F2 보다 F1의 매개변수 개수가 더 많음 f2 = f3; // 타입에러 반환 타입이 다름
함수 타입 A가 함수 타입 B로 할당 가능하기 위한 조건은 다음과 같다.