TypeScript #5 타입 호환성 (Type Compatiblility)

JohnKim·2021년 8월 30일
1

typescript

목록 보기
4/4
post-thumbnail

타입 호환성이란?

어떤 타입을 다른 타입으로 취급해도 되는지 판단하는 것

인터페이스 타입 호환성

타입스크립트는 값 자체의 타입보다는 값이 가진 내부 구조에 기반해서 타입 호환성을 검사하는데
이를 덕 타이핑(duck typing) 또는 구조적 타이핑(structural typing)이라고 한다.

인터페이스 할당 조건

인터페이스 A가 인터페이스 B로 할당 가능하려면 다음 조건을 만족해야 한다.

  • B에 있는 모든 필수 속성의 이름이 A에도 존재해야 함

  • 같은 속성 이름에 대해, A의 속성이 B의 속성에 할당 가능해야 함

interface Restaurant {
	name: string;
	star: number;
}



let chroad3: Restaurant;  // chroad3 변수 선언

let chroad3withAddress = {   // chroad3withAddress 변수 선언하고 초기화
	name: "십분의일",
	star: 5,
	address: "을지로3가",
};

chroad3 = chroad3withAddress;

Restarunt 타입은 name과 star 두 가지 프로퍼티만 있기 때문에, chroad3 변수에
address를 추가한 객체를 할당했으면 오류가 났을 것이다.

하지만 address 프로퍼티가 추가된 chroad3withAddress를 chroad3 변수에 할당하면 오류가 없다. 이는 타입 호환성 때문이다.

chroad3withAddress는 앞에서 배웠던 타입추론에 따라 자기만의 타입을 갖게 된다.
Restaurant와 같이 인터페이스 타입으로서 타입 이름이 있는 것은 아니지만, 이름이 없는 아래와 같은 구조의 타입이 된다.

{
	name: string;
	star: number;
	address: string;
}

chroad3withAddress의 타입과 chroad3의 타입은 서로 다른데 잘 호환되었다는 말입니다.

타입이 호환되기 위한 조건은 이렇게 할당하고자 하는 타입(chroad3withAddress)이 할당될 타입(chroad3)의 구조와 내부 타입이 같아야 한다. 이러한 개념을 Structural typing(구조적 타이핑) 이라고 한다. chroad3withAddress의 타입과 chroad3의 타입 자체는 서로 다르지만 chroad3withAddress은 chroad3의 구조를 모두 포함하면서 범위가 더 크다.

선택적 프로퍼티가 타입 호환성에 미치는 영향

Person의 age가 선택 속성이라면 Person은 Product에 할당 가능하지 않음

interface Person {
    name: string;
    age?: number;
}
interface Product {
    name: string;
    age: number;
}
const person: Person = { name: 'mike', };
const product: Product = person; // 타입 에러

추가 속성과 유니온 타입이 타입 호환성에 미치는 영향

추가 속성이 있으면 값의 집합은 작아지고, 반대로 유니온 타입이 있으면 값의 집합은 더 커진다.

interface Person {
    name: string;
    age: number;
    gender: string;
}
interface Product {
    name: string;
    age: number | string;
}
  • 추가 속성이 있으면 값의 집합은 더 작아지므로 Person을 Product에 할당하는 데는 문제가 없음

  • 유니온 타입으로 속성 타입의 범위가 넓어지면 값의 집합은 더 커지기 때문에 역시 Person을 Product에 할당하는 것에 문제가 되지 않음


숫자와 문자열의 타입 호환성

숫자와 문자열 타입은 서로 포함 관계에 있지 않기 때문에 서로 할당 가능하지 않다.

반면 숫자의 집합은 number | string 값의 집합에 포함되기 때문에 숫자는 number | string 타입에 할당이 가능하다.

function func1(a: number, b: number | string){
    const v1: number | string = a;
    const v2: number = b; // 타입 에러 (number는 number | string에 할당 가능)
}
function func2(a: 1 | 2){
    const v1: 1 | 3 = a; // 타입 에러 (2 가 1 | 3에 포함되지 않기 때문)
    const v2: 1 | 2 | 3 = a;
}

0개의 댓글