React 프로젝트를 TypeScript로 시작하는 것은 이제 선택이 아니라 기본에 가깝습니다. 컴포넌트의 Props, 상태(State), 이벤트, API 응답까지 모든 흐름을 타입으로 고정할 수 있기 때문에 규모가 커질수록 유지보수성과 안정성 차이가 크게 벌어집니다.
React + TypeScript 프로젝트를 처음 시작할 때 가장 많이 쓰이는 방식과 실무 기준 설정 포인트를 정리합니다.
React + TypeScript를 쓰는 이유
React에서 TypeScript를 사용하는 가장 큰 이유는 다음과 같습니다.
- Props 타입이 명확해 컴포넌트 사용 실수 감소
- 상태 구조가 커져도 안정적으로 관리 가능
- 리팩토링 시 컴파일 단계에서 오류 감지
- IDE 자동완성 및 탐색성 대폭 향상
특히 팀 단위 개발이나 중·대형 프로젝트에서는 TypeScript 없는 React는 거의 관리가 불가능해집니다.
프로젝트 생성 (Vite 기준)
최근 실무에서는 Vite + React + TypeScript 조합이 가장 많이 사용됩니다.
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev
이 방식의 장점은 다음과 같습니다.
- 빠른 개발 서버
- 불필요한 설정 최소화
- TypeScript 기본 세팅 포함
기본 폴더 구조 이해하기
생성된 프로젝트의 핵심 구조는 다음과 같습니다.
src/
main.tsx
App.tsx
vite-env.d.ts
main.tsx: React 진입점App.tsx: 최상위 컴포넌트vite-env.d.ts: Vite 전용 타입 정의
React + TypeScript 프로젝트에서는 .tsx 확장자가 JSX + TypeScript를 의미합니다.
첫 컴포넌트와 타입 기본
가장 기본적인 함수형 컴포넌트는 다음과 같습니다.
function App() {
return <h1>Hello React + TypeScript</h1>;
}
export default App;
TypeScript에서는 컴포넌트 반환 타입을 굳이 명시하지 않아도 JSX.Element로 자동 추론됩니다.
Props 타입 정의하기
React + TypeScript의 핵심은 Props 타입입니다.
type GreetingProps = {
name: string;
age?: number;
};
function Greeting({ name, age }: GreetingProps) {
return (
<div>
Hello {name} {age && `(age: ${age})`}
</div>
);
}
이제 컴포넌트 사용 시 타입이 강제됩니다.
<Greeting name="Alice" /> // OK
<Greeting /> // X name 누락
Props 타입 정의만으로도 컴포넌트 사용 실수를 대폭 줄일 수 있습니다.
useState와 타입
useState는 대부분 타입 추론으로 충분합니다.
const [count, setCount] = useState(0);
// count: number
다만, 초기값이 null인 경우에는 명시가 필요합니다.
const [user, setUser] = useState<User | null>(null);
이 패턴은 API 데이터 로딩 시 매우 자주 사용됩니다.
이벤트 핸들러 타입
React 이벤트는 DOM 이벤트와 타입이 다릅니다.
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
console.log(e.target.value);
}
자주 쓰이는 이벤트 타입은 다음과 같습니다.
ChangeEvent<HTMLInputElement>MouseEvent<HTMLButtonElement>FormEvent<HTMLFormElement>
API 데이터와 타입 연동
React + TypeScript에서는 API 응답 타입을 반드시 정의합니다.
type User = {
id: number;
name: string;
};
const [users, setUsers] = useState<User[]>([]);
이렇게 하면 렌더링 시점에서 잘못된 접근을 막을 수 있습니다.
users.map(u => u.name); // 안전
앞서 다룬 타입 안전한 API 응답 패턴과 함께 쓰면 가장 이상적입니다.
tsconfig.json에서 꼭 확인할 옵션
Vite 템플릿의 기본 tsconfig는 꽤 잘 되어 있지만, 아래 옵션은 반드시 확인하는 것을 권장합니다.
{
"compilerOptions": {
"strict": true,
"jsx": "react-jsx",
"noImplicitAny": true
}
}
strict 모드는 React + TypeScript에서 사실상 필수입니다.
실무에서 바로 추가하는 것들
프로젝트 시작 후 보통 아래 요소들을 빠르게 추가합니다.
- 라우팅 : react-router + 타입 안전한 params
- API 통신 : Axios + 제네릭
- 상태 관리 : React Query / Zustand
- 공통 타입 폴더 (
types/)
초기 구조를 잘 잡아두면 이후 확장이 훨씬 수월해집니다.
React + TypeScript 프로젝트의 핵심은 컴포넌트, 상태, API를 모두 “타입 계약”으로 묶는 것입니다. 초반에 타입 설계를 잘 해두면, 프로젝트가 커질수록 그 효과가 눈에 띄게 나타납니다.
- 컴포넌트 Props는 반드시 타입으로
- 상태와 API 응답 구조를 명확히
- strict 모드는 기본값
'개발 > Typescript' 카테고리의 다른 글
| [TYPESCRIPT] Context API와 TypeScript — 전역 상태를 안전하게 설계하는 방법 (0) | 2026.01.01 |
|---|---|
| [TYPESCRIPT] React Props와 State 타입 정의 — 컴포넌트 안정성을 결정하는 핵심 (0) | 2025.12.31 |
| [TYPESCRIPT] TypeORM + TypeScript 사용하기 — 엔티티부터 실무 설계까지 (0) | 2025.12.29 |
| [TYPESCRIPT] NestJS에서 TypeScript 활용하기 — “타입을 설계의 중심”으로 가져오는 실무 패턴 (0) | 2025.12.28 |
| [TYPESCRIPT] TypeScript + Express 프로젝트 설정하기 (0) | 2025.12.27 |
