[TS] Interface 와 Type Aliases

imzzuu·2022년 8월 25일
0
post-thumbnail

인프런 캡틴판교님의 타입스크립트 강의를 들으며 정리한 interface와 타입별칭에 관한 글입니다.

Today’s Key Point
1. Interface
2. Type Aliases
3. Interface 와 Type Aliases 차이

Interface! 어떨 때 필요할까?

Type정의 즉 Type Annotation을 하다보면 반복적인 타입들을 계속 정의해줘야하는 경우가 생깁니다.
예를 들어 todo list의 item들은 항상 같은 타입 형태입니다.

let todoItems = [
  { id: 1, title: '안녕', done: false },
  { id: 2, title: '타입', done: false },... 
]

이런식으로 말이죠!
이 todoItems에 타입을 정의하자면 아래와 같을 것입니다.

// 방법1
let todoItems: object[] 

// 방법 2
let todoItems: { id: number; title: string; done: boolean}[] 

여기까지는 문제가 없지만, todo를 구현할 때에 각각의 item을 추가, 수정, 삭제 등을 하는 함수를 구현할 경우마다 인자 혹은 반환값으로 사용될 타입 정의에 모두 위와 같은 타입을 반복적으로 작성해줘야한다는 것입니다.

function fetchTodos(): { id: number; title: string; done: boolean}[] {
  const todos = fetchTodoItems();
  return todos;
}

function addTodo(
 todo: { id: number; title: string; done: boolean}[]
): void {
  todoItems.push(todo);
}
function completeTodo(
 index: number,
 todo: { id: number; title: string; done: boolean}[]
): void {
  todo.done = true;
  todoItems.splice(index, 1, todo);
}

이런식으로 작성하게 된다면, 코드의 가독성과 효율성 면에서 상당히 불리하다고 느껴집니다.
이럴때, Interface 사용하여 위와 같은 문제를 해결할 수 있습니다.

Interface

상호간에 정의한 약속 혹은 규칙으로 반복되는 타입을 정의하여 사용할 수 있습니다.
인터페이스를 주로 사용하는 경우는 아래와 같습니다.

  • 객체의 스펙 (속성과 속성의 타입)
  • 함수의 파라미터
  • 함수의 스펙 (파라미터, 반환 타입 등)
  • 배열과 객체를 접근하는 방식
  • 클래스

사용법

interface User {
  name: string;
  age: number;
}

사용예제

  1. 변수에 사용하는 경우

    const seho: User = { name: 'hi', age: 100 };
  2. 함수의 매개변수에 사용하는 경우

    function getUser(user: User) {
      console.log(user);
    }
    getUser(seho);
  3. 함수의 스펙(구조)에 사용하는 경우

    // 함수의 인수, 반환값까지 모두 한번에 정의가능
    interface SumFunction {
     (a: number, b: number): number;
    }
    
    let sum: SumFunction;
    sum = function (num1: number, num2: string): number {
     return num1 + num2;
     };
  4. 배열의 인덱싱에 사용하는 경우

    interface StringArray {
      [index: number]: string;
     }
    
    let arr: StringArray;
    arr[0] = 'hi';
    arr[1] = 10; // error
  5. 딕셔너리 패턴 (key-value 형태를 지닌 자료형 js에서는 객체)

    interface StringRegexDictionary {
    	[key: string]: RegExp;
    }
    
    let obj: StringRegexDictionary = {
    	cssFile: /\.css$/,
    	jsFile: /\.js$/
    }
    
    // => 객체의 key(index)를 접근할 때 유용
    
    Object.keys(obj).forEach((value)){
    
    })
  6. 인터페이스 확장

     // 기본 interface
    interface Person {
      name: string;
      age: number; // 옵셔널 선택자 ? 동일하게 적용 가능
    }
    
    // 위와 같은 타입을 갖고있으며, language 속성을 추가하여 확장한 interface
    interface Developer extends Person {
      language: string;
    }
    // 확장된 Developer interface를 활용한 타입 정의
    const joo: Developer = { name: 'joo', age: 20, language: 'ts' };

Type Aliases

  • 특정 타입이나 인터페이스를 참조할 수 있는 타입 변수
  • 인터페이스와 같이 특정 타입을 정의하여 별칭으로 사용하고자 할 때 주로 활용
  • 인터페이스와 같이 복잡한 타입 및 제네릭도 사용이 가능

사용법

type MyName = string;
const name: MyName = 'capt';

언뜻보면 interface와 너무나도 유사해보입니다.
하지만, 타입별칭은 그저 편하게 사용하기 위한 별칭일뿐 새로운 타입을 하나 생성한 것이라도 보기 어렵습니다.

⭐ 여기서 InterfaceType Aliases의 차이점을 짚고 넘어가보겠습니다!

Interface 와 Type Aliases의 차이점

1. 타입의 목적성 유무
위의 설명의 연장선으로 Type Aliases는 새로운 타입값을 하나 생성하는 것이 아니라 단순히 정의한 타입을 나중에 쉽게 참고할 수 있게 이름을 부여하는 것과 같습니다.

2. 확장성의 유무
interface 는 확장이 가능한데 반해 타입별칭은 확장이 불가능합니다.
따라서 가능한 type보다는 interface로 선언해서 사용하는 것을 추천합니다.

profile
FrontenDREAMER

0개의 댓글