타입 호환
타입스크립트 코드에서 특정 타입의 호환성을 의미한다. 아래코드는 타 언어였다면 바로 에러가 일어났을 것이다.
interface Ironman { name: string; }
class Avengers { name: string; }
let m: Ironman;
m = new Avengers();
하지만 JS는 기본적으로 객체 리터럴, 익명함수 등을 사용하므로 명시적인 타입 지정보다 코드의 구조 관점에서 타입을 지정하는 것이 나은 편이다.
구조적 타이핑
- 코드 구조 관점에서 서로 호환되는지를 판단하는 것.
interface Avengers {
name: string;
}
let hero: Avengers;
// 타입스크립트가 추론한 타입은 { name: string; location: string; } 입니다.
let Iron = { name: "Ironman", location: "Pangyo" };
hero = Iron;
- 위 코드에서 Iron이 hero와 호환되는 이유는 속성 중에 name이 공통되기 때문. 따라서 Iron 이 Avengers 와 호환된다.
- 함수 호출 시에도 마찬가지.
function assemble(a: Avengers) {
console.log("Avengers assemble", a.name, a.location);
}
//타입 추론: { name: string; location: string; }
assemble(Iron);
Soundness
타입스크립트는 컴파일 시점에 타입을 추론할 수 없는 타입에 대해서는 안전하다고 간주한다. 이를 soundness 하다고 한다.
Enum 타입 호환
Enum 타입은 number 타입과 호환되지만, enum 끼리는 호환되지 않는다.
enum Status { Ready, Waiting };
enum Color { Red, Blue, Green };
let status = Status.Ready;
status = Color.Green; // Error
클래스 타입 호환
클래스 타입은 클래스 타입끼리 비교할 때 static member와 생성자를 제외하고 속성만 비교한다.
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
즉, 구조적으로 동일한 타입 handsize 를 가지므로 서로 호환된다.
제네릭 타입 호환
제네릭 타입 간 호환 여부는 <T> 가 속성에 할당 되었는지를 기준으로 한다.
interface Empty<T> {
}
let x: Empty<number>;
let y: Empty<string>;
x = y; // OK, because y matches structure of x
해당 예시는 속성이 없으므로 서로 같은 타입으로 간주된다.
interface NotEmpty<T> {
data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;
x = y; // Error, because x and y are not compatible
그런데 이처럼 속성이 있어서 제네릭의 타입 인자가 속성에 할당된다면 서로 다른 타입으로 간주된다.
'언어 > TypeScript' 카테고리의 다른 글
Type Assertion (as 사용법) (0) | 2025.04.16 |
---|---|
type vs interface (0) | 2025.04.16 |
타입 추론 (0) | 2025.04.15 |
제네릭(Generics) (0) | 2025.04.15 |
Class 특성 (0) | 2025.04.14 |