-
[TypeScript] Type Compatibility ( 타입 호환성 )Computer Science 2023. 12. 9. 23:02
타입 호환성이란?
두 가지 타입 간에 비교를 통해 값이 할당 가능한지 여부를 나타내는 것 입니다. 즉 다른 타입이 해당 타입안에 들어올 수 있는지 판단합니다.
TypeScript의 타입 호환성은 명목적 타이핑 ( nominal typing )이 아닌 구조적 서브 타이핑 ( subtyping ) 을 기반으로 합니다.
구조적 타이핑이란 오직 맴버만으로 타입을 확인하는 방식입니다.
interface test1 { test: string; } class test2 { test: string; } let test3: test1; test3 = new test2(); // 맴버가 같기에 가능합니다.
함수의 비교
let first = (test: string) => "test"; let second = (test: string, test2: string) => "test"; second = first; // OK first = second; // Error
함수의 비교에서는 매개변수를 서로 비교합니다.
second는 first의 모든 매개변수를 가지고 있기에 호환이 가능하지만 first는 second의 test2 를 가지고 있지 않기에 에러를 반환합니다.
열거형의 비교
enum Test1 { A, B, C, } enum Test2 { A = 1, B, C, } let test = Test1.A; test = Test1.B; // OK test = Test2.A; // Error
열거형은 단순하게 다른 열거형 타입의 열거형과는 호환되지 않습니다. 다만 같은 열거형 내에서는 호환이 가능합니다.
클래스의 비교
class Test1 { test: string; testFunc() { console.log("test"); } constructor(test1: string, test2: string) { this.test = test1; } } class Test2 { test: string; static test2: string; testFunc() { console.log("test"); } constructor(test1: string) { this.test = test1; } } let firstTest: Test1; let secondTest: Test2; firstTest = secondTest; // OK secondTest = firstTest; // OK
클래스 타입의 비교는 오직 인스턴스의 맴버만 비교를 진행합니다.
즉 정적 맴버 ( static ) 과 생성자 ( constructor ) 는 호환성에 영향을 주지 않습니다.
제네릭의 비교
interface Test<T> {} let test1: Test<string>; let test2: Test<number>; test1 = test2; // OK test2 = test1; // OK interface Test<T> { test: T; } let test1: Test<string>; let test2: Test<number>; test1 = test2; // Error test2 = test1; // Error
제네릭 타입에서 중요한 것은 결국 결과 타입입니다. 들어가는 Type이 중요한 것이 아닌 결과 인자를 비교합니다.
따라서 처음 호환은 전부 가능하지만 두번째부터는 불가능합니다.
Freshness ( 신선도 ) 란
type Test = { name: string; age: number; } function testFunction(test: Test) { console.log(test.name); } let testInput = { name: 'test', age: 10, test: 'test' } testFunction(testInput); // OK testFunction({ name: 'test', age: 10 }); // OK testFunction({ name: 'test', age: 10, test: 'test' }); // Error
TypeScript는 신선도라는 개념을 제공하는데, 모든 object literal 은 초기에 "fresh" 로 간주합니다.
다만 type assertion ( 타입 단언 )을 하거나, 타입 추론에 의해 object literal 의 타입이 확장되면 "fresh" 가 사라집니다.
"fresh" 상태에서는 타입호환을 허용하지 않습니다. 그렇기에 위와 같은 경우에서 마지막에는 Error가 발생합니다.
'Computer Science' 카테고리의 다른 글
쿠키 ( Cookie ), 세션 ( Session ) (0) 2024.01.05 [Java] Java version 별 차이 ( 7, 8, 9, 11 ) (0) 2023.12.12 [JavaScript] Object VS Map ( 성능 비교 ) (1) 2023.12.02 TCP ( Transmission Control Protocol ) (1) 2023.12.01 OSI model ( OSI 7 Layer ) (0) 2023.11.28