개발새발
React 타입 분석하기 본문
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로 전역에서도 사용 가능 |
참고 링크
'Typescript' 카테고리의 다른 글
| JSX 타입 이해하기 (0) | 2025.05.24 |
|---|---|
| React Hooks 분석하기 (2) | 2025.05.24 |
| axios의 타입을 어떻게 찾았는지 이해하기 (0) | 2025.05.17 |
| 다양한 모듈 형식으로 js 파일 생성하기 (0) | 2025.05.17 |
| Axios 직접 타이핑하기 (0) | 2025.05.15 |