프론트엔드/TypeScript

[TypeScript] Interface(인터페이스)란 무엇일까?

zero2-pooh 2023. 7. 15. 23:05

(Interface) 인터페이스란?

- 인터페이스는 일반적으로 타입 체크를 위해 사용되며 변수, 함수, 클래스에 사용할 수 있다. 

- 타입스크립트의 인터페이스는 두 개의 시스템 사이에 상호 간에 정의한 약속 혹은 규칙을 포괄하여 의미한다.

- 혹은 객체의 껍데기 또는 설계도라고 할 수 있다.

❗️즉, 프로그래밍에서 클래스 또는 함수의 '틀'을 정의하는 것처럼, 타입의 '틀'로서 사용할 수 있는 것이 인터페이스인 것이다.

 

⚠️그러나
인터페이스는 프로퍼티와 메소드를 가질 수 있다는 점에서 클래스와 유사하나 직접 인스턴스를 생성할 수 없고❌ 모든 메소드는 추상 메소드이다. 

 

이번 포스팅은 인터페이스의 종류에 대해 일부 포스팅을 해보겠다.


선택적 프로퍼티(Optional Properties)

인터페이스를 사용할 때 인터페이스에 정의되어 있는 속성을 반드시 모두 다 꼭 사용해야 한다면 코드의 유연성이 사라지기 마련이다.

너무 하나하나씩 따지면 일일이 구조마다 인터페이스를 생성해야 할지도 모른다.

 

🙌🏻 선택적 프로퍼티(Optional Properties)는 이를 해결할 수 있는 간편한 연산자이다.

콜론(:) 앞에 물음표(?)를 붙이면 이 속성은 옵션 속성이 되고,?를 붙이며 생략하여도 에러가 발생하지 않는다.

ex)  user?: string;


  • 예시 1
interface Users {
  userEmail: string;
  password: string;
  age?    : number;
  address?: string;
}

const users: Users = {
  userEmail: 'banana@gmail.com',
  password: '1234'
}

console.log(users); // 에러 발생하지 않음❌

 

  • 예시 2
interface Users {
   name: string;
   age: number;
   gender?: string;
}

let user: Users = {
   name: 'celine',
   age: 20,
};

user.age = 10;
user.gender = "female"; // 선택적 프로퍼티에 의해서 나중에 속성값을 넣어줄수도 있다.

user.hight = ''; // ⚠️아예 정의되지도 않는 속성을 마음대로 집어넣을 수는 없다.

읽기 전용 프로퍼(Readonly properties)

읽기 전용 속성은 인터페이스로 객체를 처음 생성할 때만 값을 할당하고 그 이후에는 변경할 수 없는 속성을 의미한다.

readonly 속성을 앞에 붙이면 간단하게 적용된다.

interface Score {
    readonly x: number;
    readonly y: number;
}

인터페이스로 객체를 처음 선언하여 값을 대입할 때는 문제가 없다.

❗️그러나 그 후에 따로 프로퍼티에 접근해서 수정하려고 하면 오류가 나게 된다.

interface User {
   name: string;
   age: number;
   gender?: string;
   readonly birth: number; // 읽기 전용 속성
}

let user: User = {
   name: 'celine',
   age: 20,
   birth: 0719, // 최초에 값을 초기화 할때만 할당이 가능
};

user.birth = 0701; // Error🚫 -> 이후에는 수정이 불가능

 

readonly VS const 

readonly와 const 는 처음 초기화 할 때만 값을 선언하고, 그 후에는 값을 수정하지 못한다는 점에서 유사하다.
다만❗️ 이 둘은 사용처가 다른데, 변수는 const를 쓰고 프로퍼티는 readonly를 사용된다는 점만 기억하면 된다.

 

 

 

readonly 활용

만약 모든 속성 readonly일 경우?

👉🏻 일일히 프로퍼티마다 readonly를 찍어주지 말고, 따로 Utility(유틸리티)Assertion(단언)타입을 활용해 구현이 가능하다!!

 

 

  • Only readonly 
// readonly 무자비로 추가
interface User {
  readonly name: string,
  readonly age: number
}

let user: User = {
  name: 'Park',
  age: 20
};

user.age = 30; // Error🚫
user.name = 'Kim'; // Error🚫

 

  • readonly Utility 
// Readonly Utility 활용
interface User {
  name: string,
  age: number
}

let user: Readonly<User> = { // Array 처럼 따로 Readonly 라는 자료형이 있다고 생각하면 된다
  name: 'Park',
  age: 20
};

user.age = 30; // Error🚫
user.name = 'Kim'; // Error🚫

 

  • Type Assertion
// Assertion 타입
let user = {
  name: 'Park',
  age: 20
} as const; // 따로 인터페이스를 사용하지 않고 객체 데이터 자체에 'as const'를 붙이게 되면 이 자체가 리터럴 타입이 된다.

user.age = 30; // Error🚫
user.name = 'Kim'; // Error🚫

인터페이스 확장(extends)

- class와 같이 인터페이스도 인터페이스 간 확장이 가능하다.

자바스크립트 클래스에서 상속을 할 때 키워드를 사용하는데 그대로 인터페이스에서도 사용해 주면 된다!!

 

  • Interface
// Interface
interface Person {
   name: string;
}

interface Worker extends Person {
   job: string;
}

let fe: Worker = { name: 'Park', job: 'Developer' };

 

  • Type
// Type
type Person = { name: string };

type Worker = Person & { job: string };

let fe: Worker = { name: 'Pakr', job: 'Developer' };
❗️특이한 점은 인터페이스 확장은 여러 개의 extends가 가능하다는 점이다. (클래스는 반드시 하나만 extends 할 수 있다)
ex) interface Worker extends Person, ooo{...}

인터페이스 함수 타입

- 인터페이스는 JavaScript 객체가 가질 수 있는 넓은 범위의 형태를 기술할 수 있다.

- 프로퍼티로 객체를 기술하는 것 외에, 인터페이스는 함수 타입을 설명할 수 있는데,

👉🏻 그러기 위해서 인터페이스에 호출 서명 (call signature)를 전달한다. 이는 매개변수 목록과 반환 타입만 주어진 함수 선언과 비슷하다. ❗️각 매개변수는 이름과 타입이 모두 필요하다.

 

 

호출 시그니처 (call signature)

interface SearchFunc {
    (source: string, subString: string): boolean;
}

 

 

한번 정의되면, 함수 타입 인터페이스는 다른 인터페이스처럼 사용할 수 있다. 여기서 함수 타입의 변수를 만들고, 같은 타입의 함수 값으로 할당하는 방법을 보여준다.

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    let result = source.search(subString);
    return result > -1;
}

 

 

올바른 함수 타입 검사를 위해, 매개변수의 이름이 같을 필요는 없다. 예를 들어, 위의 예제를 아래와 같이 쓸 수 있다.

let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
    let result = src.search(sub);
    return result > -1;
}

 

 

함수 매개변수들은 같은 위치에 대응되는 매개변수끼리 한 번에 하나씩 검사한다. 

let mySearch: SearchFunc;
mySearch = function(src, sub) {
    let result = src.search(sub);
    return result > -1;
}

 

 

함수 표현식이 숫자 나 문자열을 반환했다면, 타입 검사는 반환 타입이 SearchFunc 인터페이스에 정의된 반환 타입과 일치하지 않는다는 에러를 발생시킨다.

let mySearch: SearchFunc;

// error: Type '(src: string, sub: string) => string' is not assignable to type 'SearchFunc'.
// Type 'string' is not assignable to type 'boolean'.
mySearch = function(src, sub) {
  let result = src.search(sub);
  return "string";
};

👉🏻 이 외에도 종류는 더 있지만 포스팅은 일단 여기까지! 추후에 더 추가해보려고 한다. 🖐🏻

 

 

 

 

 

 

참고

https://velog.io/@soulee__/TypeScript-Interface-2

https://poiemaweb.com/typescript-interface

https://inpa.tistory.com/entry/TS-📘-타입스크립트-인터페이스-💯-활용하기

https://typescript-kr.github.io/pages/interfaces.html