본문 바로가기
TypeScript

0060. TypeScript 공부하기9 - 인터페이스, 표기법, 확장, 선언 합치기, 모듈 보강

by 보초코더^_^;; 2024. 2. 11.
반응형

섹션 5. 인터페이스

1강. 인터페이스

1) 인터페이스란?

인터페이스 : 상호 간에 약속된 규칙

타입에 이름을 지어주는 또 다른 문법

+ 객체의 구조를 정의하는데 특화된 문법

(타입 별칭에서는 제공하지 않는 상속, 합침 등의 객체 타입을 다루는 여러 특수한 기능을 제공함)

 

인터페이스를 잘 알면 객체 타입 정의를 할 때 다양한 방법을 활용할 수 있다.

 

interface Person { //객체 타입 정의
    readonly name: string; //읽기전용으로 설정 가능
    codingLevel?: number; //선택적 프로퍼티로 설정 가능
    sayHi: () => void; //type 표현방식
    sayHi2 () : void; //호출시그니처, 매서드의 이름이 소괄호 앞에 붙는다.
}

type Func = { //객체 타입을 별칭으로 하듯 정의
    (): void; //함수의 호출 시그니처
}

const func: Func = () => {}; //실제로 함수타입을 정의하는 타입이 된다.

const person: Person = { //interface로 만든 타입도 타입 별칭으로 만든 타입들과 동일하게 타입 주석을 이용하여 변수의 타입을 정의할 때 사용할 수 있음
    name: "초보코딩",
    sayHi: function () { //함수(메서드) 삽입 가능
        console.log("Hi~")
    },
    sayHi2: function () {
        console.log("HiHi~~")
    }
}

person.name = "홍길동"; //에러 : 위에서 읽기전용으로 설정했기 때문.

interface도 일반적인 문법은 크게 다르지 않다.

 

다만, 오버로드시 호출 시그니처로 처리하는 것을 권장한다.

 

 

2) 타입 별칭과의 차이점

interface는 객체 타입을 정의하는데 특화되어 있기 때문에 타입 별칭과는 차이점이 존재한다.

인터페이스는 Union과 Intersection 이용할 수 없다.

 

그렇기 때문에 타입 별칭에 활용하든지

type Type1 = number | string | Person; //유니온 타입
type Type2 = number & string & Person; //intersection 타입

 

타입 주석에 활용해야 한다.

const person: Person | number = { }

 

 

3) 인터페이스 표기법

헝가리안 표기법 : IPerson

인터페이스를 표기하기 위해 제일 앞의 문자를 대문자로 표기한다. 자바스크립트에서는 자주 쓰지 않는다.

 

- 참고) 자바스크립트의 주된 표기법

  • 스네이크 표기법 : user_name
  • 카멜 표기법 : userName
  • 파스칼 표기법 : UserName

 

표기법은 팀과 회사를 따라가는 것이 맞기 때문에 정답은 없다.

 

2강. 인터페이스 확장하기

1) 인터페이스 확장

타입 별칭에는 없지만 인터페이스에만 있는 기능

이렇게 interface로 객체정의할 때, 겹치는 부분이 많이 생길 수 있다.

위의 상황에서 겹치는 프로퍼티인 name과 color를 제거하고 extends를 사용한다.

interface Animal {
    name: string;
    color: string;
}

interface Dog extends Animal {
    isBark: boolean;
}

 

확장 : 기존의 것을 가지고 있는 상황에서 추가하는 개념

  • interface Dog는 interface Animal을 확장하는 개념이라는 것을 정의
    -> name, color(기존) + isBark(추가)

3개의 프로퍼티를 모두 갖고 있다는걸 확인할 수 있다.

 

확장은 상속이라고도 한다.

  • 상속 : 부모님으로부터 모두 물려받는 것
    → 슈퍼타입으로부터 모든 프로퍼티를 물려받는 것

 

 

2) 상속 타입 재정의

상속을 받는 인터페이스에서 동일한 프로퍼티의 타입을 다시 정의할 수 있다.

  • 다만, 재정의하려는 타입이 원본 타입의 서브 타입이어야 한다.
    예) string → string literal
    Animal이 Dog의 슈퍼 타입이므로 확장이 가능한 것이다. 그래서 재정의 타입이 원본의 서브가 아니면 안 된다.
interface Dog extends Animal {
    name : "hello"; // string literal type
    isBark: boolean;
}

const dog: Dog = {
    name: "", // string literal type으로 재정의된다. (오류 : '""'형식은 '"hello"' 형식에 할당할 수없습니다) 
    color: "",
    isBark: true,
}

 

3) 객체 타입 확장

type Animal = {
    name: string;
    color: string;
}

interface Dog extends Animal {
    name : "hello"; // string literal type
    isBark: boolean;
}

interface → type 별칭이었다고 해도 확장이 가능하다.

결론적으로, 인터페이스는 객체타입이면 다 확장할 수 있다.

 

 

4) 다중확장

interface DogCat extends Dog, Cat {}

const dogCat: DogCat = {
    name: "",
    color: "",
    isBark: true,
    isScratch: true,
}

한 번에 여러 개로도 확장 가능하다.

 

인터페이스는 객체타입을 다룰 때, 매우 유용하기 때문에 알아두면 좋다.

 

 

3강. 인터페이스 선언 합치기(Declaration Merging)

1) 인터페이스 선언 합치기와 확장

타입 별칭과 달리, 인터페이스는 동일한 이름으로 선언해도 문제가 되지 않는다.

타입 별칭은 두 번 정의하면 오류가 발생한다.

interface는 중복 선언이 가능하고, 중복 선언하는 경우 모든 선언이 합쳐진다.

 

하지만, 인터페이스의 선언 합침에서 충돌은 허용되지 않는다.

그래서 타입도 동일하게 해줘야 한다.

 

인터페이스 확장과 혼동할 수 있는데, 명확히 구분해야 한다.

  • 선언 합치기 : 반드시 같은 타입으로 해야 한다. (sub 타입도 불가)
  • 확장 : sub 타입이기만 하면 된다.

 

2) 모듈 보강

선언 합치기는 일반적인 경우에서는 잘 쓰지 않는다.

라이브러리의 모듈이 부실하거나 통합해야 하는 경우에 사용한다.

 

이 경우, Lib이라는 라이브러리는 모듈화가 끝났기 때문에 건드리는 것이 좋은 선택은 아니다.

이럴 때, c를 추가하기 위해서 선언 합치기를 사용할 수 있다.

 

사실 정확하게 설명하면 모듈은 node_modules에 들어있기 때문에 선언 합치기를 하려면 모듈을 불러온 다음에 해야 한다.

하지만 여기서는 개념을 설명하는 파트이므로 생략한 것이다.

 

 

반응형