[TypeScript] 타입 호환(Type Compatibility)

Dodam·2024년 1월 19일
0

[TypeScript]

목록 보기
9/11
post-thumbnail

타입 호환(Type Compatibility)

타입 호환이란 타입스크립트 코드에서 특정 타입이 다른 타입에 잘 맞는지를 의미한다.

interface Ironman {
	name: string;
}

class Avengers {
	name: string;
}

let i: Ironman;
i = new Avengers(); // OK

자바스크립트는 기본적으로 객체 리터럴이나 익명 함수 등을 사용하기 때문에 명시적으로 타입을 지정하는 것보다는 코드의 구조 관점에서 타입을 지정하는 것이 더 잘 맞는다.

구조적 타이핑

구조적 타이핑(structural typing)이란 코드 구조 관점에서 타입이 서로 호환되는지의 여부를 판단하는 것이다.

interface Avengers {
	name: string;
}

let hero: Avengers;
// 타입스크립트가 추론한 y의 타입은 { name: string; location: string; }
let capt = { name: "Captain", location: "Pangyo" };
hero = capt;

Avengers 인터페이스에서 name 속성을 갖고 있기 때문에 capt는 Avengers 타입에 호환될 수 있다.

함수를 호출할 때도 마찬가지이다.

function assemble(a: Avengers) {
	console.log("어벤져스 모여라", a.name);
}
// 위에서 정의한 capt 변수. 타입은 { name: string; location: string; }
assemble(capt);

capt 변수에 이미 name 속성 뿐만 아니라 location 속성도 있기 때문에 assemble 함수의 호출 인자로 넘길 수 있다.

Soundness

타입스크립트는 컴파일 시점에 타입을 추론할 수 없는 특정 타입에 대해서 일단 안전하다고 보는 특성이 있는데,
이걸 “들리지 않는다(It is said to not be sound)”라고 표현한다.

Enum 타입 호환 시 주의사항

이넘 타입(특정 값들의 집합)은 number 타입과 호환되지만 이넘 타입끼리는 호환되지 않는다.

enum Status { Ready, Waiting };
enum Color { Red, Blue, Geen };

let status = Status.Ready;
status = Color.green;  // Error

클래스에서 타입 호환

클래스 타입은 클래스 타입끼리 비교할 때,
static member와 생성자(constructor)를 제외하고 속성만 비교한다.

class Hulk {
	handSize: number;
	constructor(name: string, numHand: number) {}
}

class Captain {
	handSize: number;
	constructor(numHand: number) {}
}

let a: Hulk;
let s: Captain;

a = s;  // OK
s = a;  // OK

제네릭에서 타입 호환

제네릭은 제네릭 타입 간의 호환 여부를 판단할 때, 타입 인자 가 속성에 할당되었는지를 기준으로 한다.

interface Empty<T> {
}
let x: Empty<number>;
let y: Empty<string>;

x = y;  // OK,

위 인터페이스는 속성(member 변수)이 없기 때문에 x와 y는 같은 타입으로 간주된다.

만약 아래와 같이 인터페이스에 속성이 있어서 제네릭의 타입 인자가 속성에 할당된다면,
인터페이스 NotEmpty에 넘긴 제네릭 타입<T>이 data 속성에 할당되었으므로 x와 y는 서로 다른 타입으로 간주된다.

interface NotEmpty<T> {
	data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;

함수에서 타입 호환

const add = function(a: number) {};
const sum = function(a: number, b: number) {};

// 1번과 2번의 차이는 sum 함수 구조 > add 함수 구조
add = sum;  // Type '(a: number, b: number) => number' is not assignable to type '(a: number) => void'.ts(2322)
sum = add;  // OK
profile
⏰ Good things take time

0개의 댓글