본문 바로가기

JavaScript/Typescript

TypeScript - 타입 호환성

일반적으로 슈퍼 타입을 서브 타입에 할당할 수 없습니다. (공변)

// sub1은 sup1의 서브 타입
let sub1: 1 = 1;
let sup1: number = sub1;
sub1 = sup1; // 오류 발생: 서브 타입에 슈퍼 타입을 할당할 수 없음

// sub2는 sup2의 서브 타입( array는 object의 서브 타입 )
let sub2: number[] = [1];
let sup2: object = sub2;
sub2 = sup2; // 오류 발생

// sub3은 sup3의 서브 타입( 타입이 같은 요소를 가진 tuple은 array의 서브 타입 )
let sub3: [number, number] = [1,2];
let sup3: number[] = sub3;
sub3 = sup3; // 오류 발생

// any의 경우 예외적인 상황
let sub4: number = 1;
let sup4: any = sub4;
sub4 = sup4;

let sub5: never = 0 as never;
let sup5: number = sub5;
sub5 = sup5; // 오류 발생

// Dog는 Animal의 서브 타입(상속 관계)
class Animal {}
class Dog extends Animal {
  bark() {}
}

let sub6: Dog = new Dog();
let sup6: Animal = sub6;
sub6 = sup6; // 오류 발생

// Primitive Type
let sub7: string = '';
let sup7: string | number = sub7;

// Object Type
let sub8: { a: string; b: number } = { a: '', b: 1 };
let sup8: { a: string | number; b: number } = sub8;

// Array Type
let sub9: Array<{ a: string; b: number }> = [{ a: '', b: 1 }];
let sup9: Array<{ a: string | number; b: number }> = sub9; // 오류 발생

 

함수의 경우엔 반대로, 매개변수의 타입이 같거나 슈퍼 타입인 경우만 할당이 가능합니다.

class Person {}
class Developer extends Person {
  coding() {}
}
class StartupDeveloper extends Developer {
  burning() {}
}

function tellme(f: (d: Developer) => Developer) {}

// Developer => Developer 함수를 할당
tellme( (d: Developer): Developer => new Developer() );

// Person => Developer 함수를 할당
tellme( (d: Person): Developer => new Developer() );

// StartupDeveloper => Developer 함수를 할당
tellme( (d: StartupDeveloper): Developer => new Developer() );
// 오류 발생: 매개변수의 Developer는 StartupDeveloper 보다 상위 타입이기 때문에 할당할 수 없음

 

/* strict 모드 사용 중.. */

let C: { a: string } = { a:'1' };
let D: { a: string | number } = { a:2 };

C = D; // 공변: 넓은 애가 좁은 애한테 들어가지 못함(오류)

/* Object인 B는 A를 포함하고 있으므로 B는 A의 서브 타입이다. */
let A: { a:string } = { a:'1' };
let B: { a:string, b:string, c:string } = { a:'0', b:'1', c:'2' };

A = B; // 좁은 애가 넓은 애한테 들어가고 있음(공변)

let FA = (param: {a: string }) => null
let FB = (param: {a: string, b: string} ) => null

FA = FB; // 오류: 좁은 애가 넓은애로 들어가야 되는데 안 들어가짐(반공변)

// 파라미터
let PA = (p: number ) => null;
let PB = (p: number | string ) => 1;

PA = PB; // 오류: 넓은애가 좁은 애한테 안 들어가짐(공변)

// 리턴
let RA = (): number => 1;
let RB = (): number | string => '1';

RA = RB; // 오류: 넓은 애가 좁은 애한테 안 들어가짐(공변)

'JavaScript > Typescript' 카테고리의 다른 글

TypeScript - class  (0) 2022.01.13
TypeScript - interface  (1) 2022.01.12
TypeScript - Type System  (0) 2022.01.10
TypeScript - Type의 종류  (1) 2022.01.10
TypeScript - 기본 개념과 설치해보기  (0) 2022.01.06