티스토리 뷰

Typescript는 굉장히 까다로운 친구로, Props로 데이터를 전달 받았다면 해당하는 데이터의 타입을 정의해주어야 사용가능하다.

 

이때 총 3가지 방법이 있는데, 동일하게 Generic(제너릭)을 사용한다. interface / type / 직접정의 하는 방법이다.

 

빠르게 살펴보도록하자.

 

/////////////
// App.tsx //
/////////////
import React from "react";

import TodoList from "./components/TodoList";

const App: React.FC = () => {
  // ts 구간
  const todos = [{ id: "1", text: "Finish the course" }];
  return (
    // html 구간
    <div className="App">
      <TodoList items={todos} />
    </div>
  );
};

export default App;

 

위는 상위 컴포넌트의 역할을 할 TodoList 컴포넌트 출력 페이지이며, 변수 todos가 정의되어있다. Typescript이므로 App Component를 React.FC를 통해 리액트의 Function Component임을 명시하고, 화살표 함수를 사용하여 JSX 요소를 return받는다. 내부에 데이터는 Array 내부에 Object가 들어있다. Object의 value는 모두 문자열로 정의 되어있다.

 

그렇다면, 하위 컴포넌트를 살펴볼까?

 

/////////////////////////////
// components/TodoList.tsx //
/////////////////////////////

import React from "react";

const TodoList: React.FC<{ items: { id: string; text: string }[] }> = (props) => {
  return (
    <ul>
      {props.items.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

export default TodoList;

 

위 방식은 React.FC Generic 내부에 직접 정의한 경우이다. 전달받은 items를 타입 명시하는 것과 동일하게 정의해둔 것이다. 별로 어렵지 않다.

 

/////////////////////////////
// components/TodoList.tsx //
/////////////////////////////

import React from "react";

interface TodoListProps {
  items: { id: string; text: string }[];
}

const TodoList: React.FC<TodoListProps> = (props) => {
  return (
    <ul>
      {props.items.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

export default TodoList;

 

다음은 interface로 TodoListProps 타입을 명시해준다음 React.FC의 Generic으로 넣어주는 방법이다. 앞선 방법과 거의 동일하지만 코드가 제법 깔끔해지고, 따로 타입을 관리해줄 수 있는 장점이 있다.

 

/////////////////////////////
// components/TodoList.tsx //
/////////////////////////////

import React from "react";

type TodoListProps = {
  items: { id: string; text: string }[];
}

const TodoList: React.FC<TodoListProps> = (props) => {
  return (
    <ul>
      {props.items.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

export default TodoList;

 

만약 props을 빼고 변수를 사용하고 싶다면, 구조분해 할당을 통해 props.items 가 아닌 items로 Prop받은 데이터에 접근이 가능하다. 물론 변수가 여러개 빼야할 경우 모두 작성해주어야 한다. 

/////////////////////////////
// components/TodoList.tsx //
/////////////////////////////

import React from "react";

type TodoListProps = {
  items: { id: string; text: string }[];
}

const TodoList: React.FC<TodoListProps> = ({items}) => {
  return (
    <ul>
      {items.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

export default TodoList;

 

type에는 ' = '가 들어가고 interface에는 아무것도 들어가지 않음을 주의하자. 두개 모두 객체를 정의할 때 잘 쓰이며, 위 코드에서는 동일하게 데이터 타입을 정의하고 받아오는 역할을 한다. 그럼 type과 interface의 차이가 무엇일까?

 

  Interface Type
공통점 데이터 타입을 명시하는데 사용
데이터 타입 대부분 객체(단일값 가능) 대부분 단일값(객체 가능)
확장 extends 키워드 intersection 연산자
사용 방식 등호 같은 부호가 필요없음 등호 사용

 

위의 표처럼 데이터 타입을 명시하는데 사용되나, 객체의 경우 Interface를 사용하고 단일값일때는 Type를 사용한다고 보면 된다. 물론 둘다 모든 데이터 타입을 정의할 수 있으나, 확장 방식이 extends는 객체를 확장하는데 유리하고, intersection인 |(or), &(and)은 단일값을 확장하는데 용이하기 때문이다. 여러 문서를 살펴보아도 각자 편한대로 사용하면 된다고 한다. 다만, Generic으로 사용할 때, 컨벤션을 통해 나누면 좋다고 하는데, Interface인 경우 타입명 맨 앞에 I를 붙여주고, Type인 경우 맨 앞에 T를 붙여 가독성을 높이는 방법이 있다.

 

주로 프로젝트를 진행할때 회바회겠지만, 요즘은 Type을 사용하는 추세라고 한다.

728x90

'일상코딩 > 노트' 카테고리의 다른 글

Vue : Basic Syntax 4 (computed, watch)  (1) 2024.05.03
Vue : Basic Syntax 3 (v-if, v-for)  (0) 2024.05.01
Vue : Basic Syntax 2 (v-bind, v-on)  (2) 2024.04.30
Vue : Basic Syntax 1  (0) 2024.04.29
Vue3 : Intro  (0) 2024.04.25
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함