개발새발

React 타입 분석하기 본문

Typescript

React 타입 분석하기

비숑주인 2025. 5. 24. 00:06

React는 자바스크립트로 UI를 구성할 수 있도록 도와주는 라이브러리이다. 이때 사용하는 문법인 JSX는 HTML과 유사하게 생겼지만 자바스크립트 안에서 실행되며, 타입스크립트와 함께 사용할 경우 특별한 설정이 필요하다.

이 글에서는 React 프로젝트에서 타입스크립트를 제대로 작동시키기 위한 설정과 함께, React 내부의 타입 시스템을 설명하려고 한다. 

 

1. React는 타입스크립트를 지원하는가?

React는 자체적으로 타입 선언을 제공하지 않는다. 대신 DefinitelyTyped 커뮤니티에서 관리하는 @types/react 패키지를 통해 타입 정의를 제공한다.

 

설치 명령어

npm i react@18.2.0 @types/react@18.0.28
npx tsc --init

 

설치 후 node_modules/@types/react/package.json 파일을 확인하면 다음과 같이 타입 진입점이 설정되어 있다.

"types": "index.d.ts"​

 

즉, React의 타입은 @types/react/index.d.ts 파일에서 시작된다.

2. JSX를 사용하려면 tsconfig.json을 설정해야 한다

React에서 사용하는 JSX 문법은 타입스크립트 기본 설정으로는 작동하지 않는다. test.tsx 파일을 작성하고 JSX를 포함시키면 다음과 같은 에러가 발생한다:

Cannot use JSX unless the 'jsx' flag is provided.

 

해결 방법: tsconfig.json 수정

{
  "compilerOptions": {
    "jsx": "react", // 또는 "react-jsx"
    ...
  }
}

jsx 옵션의 값 설명

옵션 값 설명
react JSX → React.createElement로 변환
react-jsx JSX → _jsx 호출로 최적화 변환 (React 17+에서 import 필요 없음)
react-native React Native 전용 설정

3. JSX와 React의 타입 관계

JSX는 코드에 React.createElement 호출을 삽입하므로, 실제로는 React 객체를 암묵적으로 사용하는 것이다. 따라서 다음 코드에서도:

const App = () => <div>Hello</div>;

 

타입스크립트는 내부적으로 다음과 같이 처리한다:

const App = () => React.createElement("div", null, "Hello");

 

즉, JSX를 사용한다면 반드시 다음과 같이 React를 import해야 한다:

import React from "react";

 

단, React 17 이상에서는 react-jsx를 설정하면 이 import 문이 필요 없도록 설계되어 있다. 내부적으로 _jsx라는 헬퍼 함수가 자동 삽입되기 때문이다.

4. React는 CommonJS 모듈이다

React는 기본적으로 CommonJS 모듈 형식으로 작성되어 있다. 다음은 @types/react/index.d.ts의 상단 부분이다:

export = React;
export as namespace React;

 

  • export = React는 CommonJS에서 사용하는 방식이다.
  • export as namespace React는 스크립트 환경(UMD 등)에서도 React라는 전역 네임스페이스를 사용 가능하게 한다.

ECMAScript 방식처럼 보이게 만들려면?

타입스크립트의 esModuleInterop 옵션이 true일 경우 다음과 같은 문법도 사용할 수 있다:

import React, { useState } from "react";

 

이는 실제로 CommonJS 모듈을 ECMAScript 스타일처럼 사용할 수 있게 해주는 트랜스파일링을 의미한다.

5. JSX가 없어도 발생하는 React 관련 에러

React 17 이상에서는 jsx: "react-jsx"로 설정하면 React를 import하지 않아도 되지만, 이전 방식에서는 다음과 같은 오류가 발생한다:

'React' refers to a UMD global, but the current file is a module.
Consider adding an import instead.

 

이는 JSX를 사용하면서도 React.createElement 호출이 존재하기 때문이며, React를 import하지 않으면 해당 호출을 해석할 수 없어 에러가 발생한다.

6. UMD 환경에서도 React 타입이 작동하는 이유

export as namespace React;

 

이 선언은 전역 스크립트 환경에서도 다음과 같이 React를 사용할 수 있게 한다:

type A = React.ElementType;

 

이 구문이 동작하는 이유는 React 타입 선언이 UMD 모듈용 네임스페이스로 정의되어 있기 때문이다. 만약 export as namespace React를 제거하면 "Cannot find namespace 'React'" 에러가 발생한다.

결론

항목 설명
React 타입 정의 @types/react 패키지를 통해 제공됨
JSX 사용 tsconfig.json의 jsx 설정이 필수
React import jsx: "react"에서는 필수, "react-jsx"에서는 생략 가능
모듈 시스템 CommonJS 기반이며 export = React로 export됨
UMD 대응 export as namespace React로 전역에서도 사용 가능

 

참고 링크