인터페이스

김동현·2022년 3월 18일
0

TypeScript

목록 보기
11/18
post-thumbnail

interface

인터페이스는 일반적으로 객체 타입을 위해 사용합니다.

interface 키워드를 통해서 인터페이스를 생성하고, 이름의 첫 글자는 대문자로 작성해줍니다. 그리고 중괄호 안에 프로퍼티 이름과 프로퍼티 값의 타입을 정의하고 끝에는 세미콜론(콤마)을 붙여줍니다.

인터페이스로 객체의 구조를 작성할 때 프로퍼티에 대한 초기값은 설정할 수 없습니다. 구체적인 값이 아닌 구체적인 구조만 작성할 뿐입니다.

메서드도 정의할 수 있습니다. 메서드의 경우 실제 메서드가 아니라 구조와 어떤 형태여야 하는지를 작성해줍니다. 즉, 매서드 이름, 매개변수의 개수, 전달받는 인수의 타입 그리고 반환값에 타입을 작성해줍니다.

정의한 인터페이스를 타입처럼 사용할 수 있으며, 위 코드처럼 user1 변수의 타입을 인터페이스인 Person으로 지정하여 user1 변수는 Person 인터페이스에 정의한 객체의 구조를 갖도록 지정합니다.

interface vs type alias

타입 별칭과 인터페이스의 차이점으로 인터페이스는 보강(augment)이 가능합니다.

위 코드처럼 속성을 확장하는 것을 "선언 병합(declaration merging)"이라고 합니다. 이는 기존 인터페이스를 다시 작성하여 기존 인터페이스와 병합이 됩니다.

타입 선언 파일의 경우 추가적으로 채워야 하는 빈틈을 보강하기 위해서 반드시 인터페이스를 통해서 타입을 명명해야 합니다.

타입 별칭은 기존 타입에 추가적인 보강이 없는 경우에만 사용해야 합니다.

implements

인터페이스를 통해서 클래스의 구조를 미리 정의할 수 있습니다.

즉, 클래스가 생성하는 인스턴스의 구조를 인터페이스에 정의한 프로퍼티와 메서드를 모두 갖도록 작성해주어야 합니다. 이때 추가적인 프로퍼티나 메서드를 가지는 것은 허용되며 에러를 발생시키지 않습니다. 단지 인터페이스에 정의한 프로퍼티와 메서드를 모두 갖고 있기만 하면 됩니다.

이때 인터페이스에 정의된 프로퍼티나 메서드는 모두 클래스의 인스턴스 프로퍼티나 프로토타입 메서드에 대한 정의이며, 정적 프로퍼티나 메서드가 아닙니다.

참고로 타입 별칭도 클래스를 implements할 때 사용 가능합니다.


User 인터페이스에 name, age, role 각 프로퍼티를 정의했습니다. 이후 UserInfo 클래스에 User 인터페스를 implements로 작성했습니다.
이때 UserInfo 클래스는 name, age, role 모두 인스턴스 프로퍼티르로 정의해야 하지만 위 코드에서 role 프로퍼티를 정적 프로퍼티로 정의하여 에러가 발생하는 것을 볼 수 있습니다.

클래스 이름 뒤 implements 키워드 뒤에 인터페이스를 작성하며, 콤마로 구분하여 여러 인터페이스 작성도 가능합니다.

위 그림처럼 Person 클래스는 Greetable 인터페이스에 정의한 것처럼 name 프로퍼티와 greet 메서드를 작성해야한다고 표시됩니다.

읽기 전용 프로퍼티

인터페이스의 프로퍼티에 raedonly를 통해 읽기 전용 프로퍼티를 정의할 수 있습니다.

주의할 점으로 인터페이스를 implements할 때 인터페이스의 읽기 전용 프로퍼티를 클래스 내 인스턴스 프로퍼티에 읽기 전용으로 작성하지 않아도 에러가 발생하지 않습니다.

즉, 읽기 전용 프로퍼티가 아닌 일반적인 인스턴스 프로퍼티로 구현해도 에러가 발생하지 않습니다.

그렇기 때문에 클래스 내 인스턴스 프로퍼티를 읽기 전용으로 구현하기 위해서는 명시적으로 인스턴스 프로퍼티에 readonly 키워드를 작성하여 프로퍼티를 구현해야 읽기 전용으로 동작하게 됩니다.

혹은 인스턴스를 할당받는 변수의 타입을 인터페이스로 지정한다면 클래스 내 인스턴스 프로퍼티에 readonly 키워드를 따로 작성하지 않더라도 읽기 전용 프로퍼티로서 동작하게 됩니다.


만약 인터페이스에 작성된 읽기 전용 프로퍼티가 생성될 인스턴스의 프로퍼티도 읽기 전용으로 동작하고자 한다면 아래와 같이 작성해주어야 합니다.

  1. 클래스 내 인스턴스 프로퍼티를 클래스 필드로 작성할 때 reaonly 키워드 명시적으로 작성
  1. 클래스 내 인스턴스 프로퍼티에 reaonly를 따로 작성하지 않고, 인스턴스를 할당받는 변수의 타입을 인터페이스 타입으로 명시

extends

인터페이스는 extends 키워드를 통해서 "서브 타입 제한"이 가능합니다. 이는 & 타입 연산자와 유사하게 포함 가능한 서브 타입을 제한하는 동작을 합니다.

타입 별칭의 경우 &(인터섹션 타입)으로 타입 제한할 수 있습니다.


Greetable 인터페이스는 Named 인터페이스를 extends 하여 정의했습니다. 그러므로 Person 클래스는 Named의 name 프로퍼티와 Greetable의 greet 메서드 모두 필요로합니다.


인터페이스는 여러 인터페이스를 extends를 통해 하나의 인터페이스로 병합하는 것도 가능합니다. 즉, extends 키워드 뒤에 여러 인터페이스를 콤마로 구분하여 작성하는 것이 가능합니다.

클래스의 extends에서는 하나의 클래스만을 확장할 수 있지만 인터페이스의 extends에서는 여러 인터페이스를 하나의 인터페이스로 확장하는 것이 가능합니다.

함수 정의

인터페이스는 객체의 구조를 정의하는데 사용된다고 했지만 함수의 구조를 정의할 때도 사용할 수 있습니다.

함수 구조를 정의하는 인터페이스는 중괄호 내부에 위 코드처럼 작성합니다. 해당 인터페이스의 구조를 갖는 add는 두 개의 매개변수를 선언해야하며, 매개변수가 전달받는 인수의 타입 또한 number이며 반환값은 number이어야 합니다.

옵셔널 프로퍼티 & 옵셔널 메서드

인터페이스는 옵셔널 프로퍼티를 작성할 수 있습니다. 즉, 선택적으로 프로퍼티를 갖도록 작성할 수 있습니다.

Info 인터페이스에서 output 프로퍼티에 콜론 앞에 ?을 작성하여 해당 프로퍼티가 존재할 수도 있지만 반드시 존재해야한 한다는 것은 아니라고 알려주는 것입니다.

메서드의 경우에는 메서드 이름 뒤에 ?을 작성하여 선택적으로 갖도록 작성할 수 있습니다.

Info 인터페이스의 구조를 갖는 클래스 Person은 name 프로퍼티 이외 age나 greet 메서드가 존재하지 않아도 에러가 표시되지 않습니다. 이는 선택적으로 구현 가능한 프로퍼티, 메서드이므로 에러가 표시되지 않습니다.

즉, implements 하는 경우 옵셔널 프로퍼티나 메서드의 경우 선택적으로 구현 가능한 프로퍼티와 메서드임을 의미합니다.

인덱스 시그니처

인덱스 시그니처는 "[키 이름: 키 타입] : 값 타입;" 형식으로 사용됩니다.

  • 키 이름은 단지 키를 나타내기 위한 용도로 어떤 이름이든 작성가능합니다.

  • 키 타입의 경우 string이나 number 또는 symbol의 조합이어야 합니다. 보통은 string 타입을 사용합니다.

  • 값 타입의 경우 어떤 타입이든 작성가능합니다. 주의할 점으로 정의된 타입 이외 다른 타입을 갖는 프로퍼티를 가질 수 없게 됩니다.

참고로 인터페이스는 매핑된 타입을 사용할 수 없습니다. 매핑된 타입은 객체 리터럴 형태의 객체 타입에서 사용할 수 있습니다.

profile
Frontend Dev

0개의 댓글