본문 바로가기
IT/JavaScript

TypeScript vs PropTypes

by 무녈 2022. 3. 9.

 

 

https://blog.logrocket.com/comparing-typescript-and-proptypes-in-react-applications/

 

Comparing TypeScript and PropTypes in React applications - LogRocket Blog

Compare TypeScript and PropTypes, tools for type checking, to determine which one best suits your project's needs.

blog.logrocket.com

"Comparing TypeScript and PropTypes in React applications"을 번역한 내용입니다.


PropTypes 와 TypeScript는 목적이 비슷하지만, 서로 다른 작동 방식을 가지고 있다.

이 두가지 tool은 무엇이고, 어떤 차이를 가지고 있는지 알아보자.

PropTypes

React 애플리케이션에서 props를 위한 runtime type-checking tool

PropTypes를 사용하면 prop의 필수여부를 명시하는 것과 같이 component에 예상되는 props의 유형을 정의할 수 있다.

component에 다른 type을 전달하거나 필요한 prop을 건너뛰면 JavaScript 콘솔에 경고가 표시된다.

import React from 'react'
import PropTypes from 'prop-types'

const NotificationCard = ({ message, type, id }) => { 
  return <span>Notification</span>
}

NotificationCard.propTypes = {
  message: PropTypes.string.isRequired,
  type: PropTypes.oneOf(["error", "warning", "success"]),
  id: PropTypes.string.isRequired
}

export default NotificationCard

 

코드를 실행 할 경우 VScode와 같은 IDE는 어떠한 오류나 경고도 보여주지 않는다.

 

브라우저 콘솔 스크린샷에서 다른 message prop의 데이터 유형이 표시되고,

message에 string을 넣어준다면, id를 가리키는 또다른 에러가 발생한다.

 

PropTypes는 production application에서 경고를 제공하지 않으며, 경고는 개발 환경에서만 나타난다.

응용 프로그램의 production version을 사용하는 동안 예기치 않은 유형이 수신되면 콘솔에서 경고를 띄우지 않는다.

✅ TypeScript

React와 함께 TypeScript를 사용하면 컴파일 시 확인될 prop에 type을 추가한다.

TypeScript는 JavaScript로 컴파일되는 과정이 필요

import React from 'react'
import PropTypes from 'prop-types'

type Props = {
  message: string;
  type: "error" | "warning" | "success";
  id: string;
}

const NotificationCard = ({ message, type, id }: Props) => { 
  return <span>Notification</span>
}

export default NotificationCard

TypeScript용 IDE 도구를 사용하면 다른 type의 prop을 전달할 때 IDE에서 warning을 즉시 받는다.

TypeScript 🆚 PropTypes

두 tool 모두 prop의 type-checking 에 사용

TypeScript가 비록 우세해 보이지만, 항상 최선을 아닐 수 있다.

 

몇 가지 큰 차이점을 살펴보자.

📌 1. 런타임 및 컴파일 시간 유형 확인

PropTypes는 애플리케이션이 브라우저에서 실행되는 런타임 동안 type 검사를 한다.

TypeScript는 TypeScript 코드가 JavaScript에 컴파일되는 컴파일 시간 동안 Type-Checking을 한다.

이것은 tool을 어떻게 사용할 수 있는지에 영향을 미치기 때문에 주목할 필요가 있다.

 

API의 데이터:

TypeScript는 API에서 전송되는 데이터를 type-check를 할 수 없다.

해당 데이터의 내용은 런타임에만 알 수 있기 때문에 그러한 코드를 컴파일하는 것은 TypeScipt가 type을 확인할 수 없게 된다.

반면, PropTypes는 예상 type을 위반할 경우 경고를 나타낸다.

...
if (typeof age !== number) {
  console.warn("Age should have a number data type")
}
...

age가 API로부터 획득하거나 하드코딩되든 타입 체커는 여전히 실행된다.

반면 TypeScript는 브라우저로 이동하지 않기 때문에 하드코딩된 데이터로 유형 확인을 제한적이다.

 

Building a component library

컴포넌트 라이브러리를 생성하는 경우 패키지 관리자에게 프로덕션 코드를 게시할 가능성이 매우 높으며, 컴파일 시 TypeScript는 JavaScript로 변환된다.

즉, 라이브러리 사용자는 PropType의 관련성을 재차 강조하면서 prop에 대한 TypeScript type 정의에 의존할 수 없다.

PropTypes는 정상적인 JavaScript 코드로서, 만든 라이브러리가 사용될 때 또한 검증이 가능하다.

 

📌 2. Syntax and semantic highlighting

두 tool 모두 component의 prop 정보를 자동 완성하는 플러그인이 있지만, TypeScript의 highliting tool이 더 좋다.

VS Code, WebStorm 및 Atom과 같은 TypeScript IDE 도구에서 많은 기능을 찾을 수 있다.

TypeScript는 예상되는 prop 데이터 유형이 제공되지 않을 때 component를 적절하게 강조하고 솔루션에 대한 통찰력을 높인다.

 

📌 3. TypeScript의 고급 기능

TypeScript에서 PropTypes가 제공할 수 없는 prop 유형을 지정할 수 있는 여러 가지 방법이 있다.

예를 들어 TypeScript는 type과 interface를 결합하고, 속성 A가 참일 경우 속성 C도 반드시 제공되어야 한다고 명시하는 등 조건부 유형 검사를 수행한다.

 

import React from "react";
import PropTypes from "prop-types";
type Props =
    | {
            type: "error";
            message: "";
      }
    | {
            type: "status";
      };
const NotificationCard = (props: Props) => {
    return <span>Notification</span>;
};
export default NotificationCard;

 

위의 코드 조각에서 다음과 같은 경우typeerror일 경우, message 프로퍼티가 필요하다.

status일 경우, 다른 property를 지정할 필요가 없다.

 

만약 message property를 제공하지 않고 error 타입을 받을 경우의 경고가 발생

 

message prop이 없는 첫 번째 NotificationCard 는 warning을 갖는 반면, 두 번째 NotificationCard 컴포넌트는 에러가 발생하지 않는다.

 

두 장점을 한 번에 가지기

Type Script와 PropTypes 중 하나를 선택하려면 절충이 필요하다.

 

사용처에 따라 최선의 선택지가 달라진다.

예를 들어, 많은 사람들이 사용할 라이브러리로 애플리케이션을 빌드하는 경우 런타임 유형 확인이 매우 중요하다.

 

런타임과 컴파일 시간 유형 검사를 모두 즐길 수 있는 방법 존재

 

첫째, 애플리케이션에 대한 type 정의와 PropTypes 정의를 쓰도록 선택 가능

두 장점을 합치기 위해 두 정의를 모두 쓰는 것은 힘들기 때문에 편한 방법을 살펴보자.

1. InferProps

@types/prop-types의 InferPropTypes은 PropTypes 정의에서 type 정의를 만드는 데 사용될 수 있다.

import React from "react";
import PropTypes, { InferProps } from "prop-types";

const BlogCardPropTypes = {
    title: PropTypes.string.isRequired,
    createdAt: PropTypes.instanceOf(Date),
    authorName: PropTypes.string.isRequired,
};

type BlogCardTypes = InferProps<typeof BlogCardPropTypes>;
const BlogCard = ({ authorName, createdAt, title }: BlogCardTypes) => {
    return <span>Blog Card</span>;
};

BlogCard.propTypes = BlogCardPropTypes;

export default BlogCard;

이제 구성요소는 PropTypes 정의를 가지고 있으며 TypeScript 유형을 위반할 때 오류를 제공한다.

Property 'authorName' is missing을 나타내지만, BlogCardPropTypes 객체에서 property에 대한 isRequired를 추가하지 않았기 때문에 createdAt의 missing을 말하지 않는다.

 

2. babel-plugin-typescript-to-proptypes

babel-plugin-typescript-to-proptypes을 사용하여 TypeScript 유형 정의에서 PropTypes를 생성할 수 있다.

prop에 대한 type을 명확히 하면, 플러그인은 이러한 type 정의를 PropTypes 정의로 변환

 

예를 들어

import React from "react";
type Props = {
    title: string;
    createdAt: Date;
    authorName: string;
};
const BlogCard = ({ title, createdAt, authorName }: Props) => {
    return <span>Blog card</span>;
};
export default BlogCard;

아래 코드와 같다.

import React from 'react'
import PropTypes from 'prop-types'

const BlogCard = ({ title, createdAt, authorName }) => {
    return <span>Blog card</span>;
};

BlogCard.propTypes = {
  title: PropTypes.string.isRequired,
  createdAt: PropTypes.instanceOf(Date),
  authorName: PropTypes.string.isRequired,
}

export default BlogCard
이에 따라 컴파일되어 런타임 동안 React 응용 프로그램 유형 검사 기능을 제공한다.
 

Conclusion

두 장점을 모두 아우를 수 없다면 TypeScript가 우세하겠지만, 적재 적소에 알맞은 type-checker를 사용하자.
 

 

반응형

'IT > JavaScript' 카테고리의 다른 글

DOMContentLoaded 이벤트 핸들링  (0) 2022.04.01
배열의 요소를 무작위로 섞기  (1) 2022.04.01
문자열 치환 (replace, RexExp, match)  (0) 2022.03.13
[JavaScript] null과 undefined  (0) 2022.01.19
렉시컬 스코프(Lexical Scope)  (0) 2021.09.17

댓글