Type Extension

Changhan·2025년 1월 26일

Typescript

목록 보기
16/29

자바스크립트에서 상속을 위해 extend라는 키워드를 사용한다. 이것을 타입스크립트에서도 사용할 수 있다.

interface IName {
  name: string;
}

// IName을 상속받음
interface ISinger extends IName {
  age: number;
}

ISinger는 IName을 상속받는다. 따라서 ISinger로 선언된 타입은 IName의 프로퍼티도 사옹할 수 있게 된다. 어떻게 보면 이전에 살펴본 interface merging과 비슷한 개념으로 생각할 수 있을 것 같다.

type 키워드를 이용한 extension

type TName = {
  name: string;
};
type IDol = TName & { age: number }; 
const idol2: IDol = {
  name: '아이유',
  age: 32,
}; // name, age 둘 다 선언이 되어야 한다.

type의 extension의 경우 intersection을 이용한다.

type과 interface extension

type TSongName = {
  songName: string;
};
type TSinger = {
  singer: string;
};

interface ISinger extends TSongName, TSinger {
  release: string;
}
const singer2: ISinger = {
  songName: '야생화',
  singer: '박효신',
  release: '2016',
};

이렇게 가져온 타입들은 모두 다 선언해줘야 한다. 하나라도 빠지면 에러가 발생한다.

여러 개의 type을 상속하여 extension

type TSongName = {
  songName: string;
};
type TRelease = {
  released: string;
};
type TSinger = {
  singer: string;
};
type TSong = TSongName & TRelease & TSinger;
const song: TSong = {
  songName: '미치게 보고 싶은',
  released: '2015',
  singer: '태연',
};

여러 개의 interface를 상속하여 extension

interface DeskWidth {
  width: number;
}
interface DeskHeight {
  height: number;
}
interface Desk extends DeskHeight, DeskWidth {
  length: number;
}
const desk: Desk = {
  width: 10,
  length: 20,
  height: 30,
};

type Overriding

type THeight = {
  height: number;
};
type TRectangle = THeight & {
  height: string;
  width: number;
};

const rectangle: TRectangle = {
  width: 100,
height: , // type: never
};

THeight에서 height 프로퍼티를 number 타입으로 선언했다. TRectangle의 height과 THeight의 height가 intersection(&) 되었기 때문에 height는 never 타입이 되는 것이다.

type TWidth = {
  width: number | string;
};
type TRectangle2 = TWidth & {
  width: number;
  height: number;
};
const rectangle2: TRectangle2 = {
  width: 100, // number로 overriding이 된다.
  height: 200,
};

extension하는 (여기서는 TWidth의 width(number | string), Twidth와 intersection되는 객체의 width(number) )
두 type의 프로퍼티가 서로 관계없는 타입이라면 never 타입이 된다. 하지만, 유니언을 사용한 경우 정확한 타입으로 narrowing이 된다.

interface Overriding

interface IHeight {
  height: number;
}
interface IRectangle extends IHeight {
  width: number;
  height: number; // 같은건 ok
  // height: string; // error
}

interface의 overriding의 경우는 type과는 조금 다르다. extension 하는 두 타입에서 중복된 프로퍼티의 타입이 다르다면 애초부터 에러를 표시해준다.

interface IWidth {
  width: number | string;
}
interface IRectangle2 extends IWidth {
  width: string; // number, string, number | string 모두 가능, 그 이외엔 안됨
  height: number;
}

만약 타입이 유니언으로 구성된 경우를 살펴보자. extension되는 두 타입이 union 형태가 존재하는 경우 union에 속한 타입만 선언이 가능하다. 그래서 interface에서 extend를 할 때 프로퍼티가 never 타입이 형성되는 경우 (ex. number & string) 아예 선언조차 할 수가 없다.

후기

상속의 개념은 자바스크립트에서 배워서 쉽게 이해할 수 있었다. 타입이 복잡해지면서 유니온과 인터섹션에 대한 개념을 확실히 이해할 필요가 있을 것 같다.

0개의 댓글