Typescript 8.타입 호환성

하비·2024년 3월 27일
0

typescript

목록 보기
8/14

Type compatibility

TypeScript의 타입 호환성은 구조적 서브 타이핑을 기반으로 함.
구조적 타이핑이란, 오직 멤버만으로 타입을 관계시키는 방식을 말함.(풀어 설명하자면, y가 최소한 x와 동일한 멤버를 가지고 있다면 x와 y는 호환됨)

interface Named {
  name: string;
}
let x: Named;
//y의 추론된 타입은 {name:string, location:string;}입니다.
let y= {name: "Alice", location:"Seattle"};
x=y

ylocation 프로퍼티를 추가적으로 갖고 있지만 오류가 발생하지 않음에 유의.
호환성을 검사할 때는 오직 대상 타입의 멤버만 고려된다.

구조적 타이핑 vs 명목적 타이핑
Java 같은 명목적 타이핑을 사용하는 언어 체계는 타입을 확장시킬 때 확장에 대한 명시를 해야한다. 하지만 Typescript는 Javascript와의 호환성을 높이기 위해 타입의 구조에 따른 호환을 제공한다. 이것을 구조적 타이핑이라고 함

범위에 따른 타입의 호환성

let a:number = 123;
let b:123 = 123;
a = b;
b = a // Error !

a는 number타입이고 b 는 number literal타입이기 때문에 number literal타입은 number타입의 하위 요소에 속하므로 a=b는 문제가 되지 않지만 반대로 하는 행위는 에러를 발생시킴.

타입은 계층 구조를 갖고 있으며 계층 구조에 따라 타입을 부여할 수 있음.

함수 타입의 호환성

x를 y에 할당할 수 있는지 검사하기 위해 제일 먼저 볼 것
1. 매개변수: x의 각 매개변수는 호환 가능한 타입을 가진 y의 해당 매개변수를 가져야함.

let x = (a:number)=>0;
let y = (b:number, s:string) => 0;
y=x; //성공
x=y; // error!
  • 매개변수 타입 비교 시: 원본 매개변수가 대상 매개변수에 할당이 가능하거나, 반대여도 할당은 성공.
    호출한 측에서 더 특수한 타입을 취하여 함수 제공이 가능하나, 덜 특수화된 타입의 함수를 호출할 수 있기 때문에 바람직 하지 않음.
enum EventType {
  Mouse,
  Keyboard,
}
interface Event {
  timestamp: number;
}
interface MyMouseEvent extends Event {
  x: number;
  y: number;
}
interface MyKeyEvent extends Event {
  keyCode: number;
}
function listenEvent(eventType: EventType, handler: (n: Event) => void) {
  /* ... */
}
// 바람직하진 않지만 유용하고 일반적임
listenEvent(EventType.Mouse, (e: MyMouseEvent) => console.log(e.x + "," + e.y));
// 건전성 측면에서 바람직하지 않은 대안
listenEvent(EventType.Mouse, (e: Event) =>
  console.log((e as MyMouseEvent).x + "," + (e as MyMouseEvent).y)
);
listenEvent(EventType.Mouse, ((e: MyMouseEvent) =>
  console.log(e.x + "," + e.y)) as (e: Event) => void);
// 여전히 허용되지 않음 (명확한 오류). 완전히 호환되지 않는 타입에 적용되는 타입 안전성(Type safety) > 왜 오류냐면 MyMouseEvent라는 특정된 타입 값이 아닌, 더 넓은 범위의 number 타입이 적용됐기 때문
listenEvent(EventType.Mouse, (e: number) => console.log(e));
  • 선택적 매개변수/나머지 매개변수: 호환성 비교시 선택적 매개변수와 필수 매개변수를 바꿔서 사용할 수 있음.(선택적 매개변수는 타입이 비교되지 않음??으로 이해해도 되는가?)
  1. 반환타입: 원본 함수의 반환 타입이 대상 타입의 반환 타입의 하위 타입이 되도록 함.
let x = () => ({name: "Alice"});
let y = () => ({name: "Alice", location: "Seattle"});
y = x; // 오류, x()는 location 프로퍼티가 없습니다.
x = y; // 성공
profile
개발자를 꿈꾸는 하비입니다

0개의 댓글