TypeScript 사용하기
TypeScript는 타입 정의를 추가해 JavaScript를 확장한 언어이다. 새로운 React Native 프로젝트는 기본적으로 TypeScript를 대상으로 하지만, JavaScript와 Flow도 지원한다.
TypeScript 시작하기
React Native CLI로 생성한 새 프로젝트나 Ignite와 같은 인기 있는 템플릿은 기본적으로 TypeScript를 사용한다.
TypeScript는 Expo와도 함께 사용할 수 있다. Expo는 TypeScript 템플릿을 제공하며, 프로젝트에 .ts
또는 .tsx
파일이 추가되면 자동으로 TypeScript를 설치하고 설정하도록 안내한다.
npx create-expo-app --template
기존 프로젝트에 TypeScript 추가하기
- 프로젝트에 TypeScript, 타입 정의, ESLint 플러그인을 추가한다.
- npm
- Yarn
npm install -D @tsconfig/react-native @types/jest @types/react @types/react-test-renderer typescript
yarn add --dev @tsconfig/react-native @types/jest @types/react @types/react-test-renderer typescript
이 명령어는 모든 의존성의 최신 버전을 추가한다. 프로젝트에서 사용 중인 기존 패키지와 버전을 맞추기 위해 버전을 변경해야 할 수 있다. React Native Upgrade Helper와 같은 도구를 사용해 React Native에서 제공하는 버전을 확인할 수 있다.
- TypeScript 설정 파일을 추가한다. 프로젝트 루트에
tsconfig.json
파일을 생성한다:
{
"extends": "@tsconfig/react-native/tsconfig.json"
}
- JavaScript 파일을
*.tsx
로 변경한다.
./index.js
엔트리포인트 파일은 그대로 두는 것이 좋다. 그렇지 않으면 프로덕션 빌드를 번들링할 때 문제가 발생할 수 있다.
tsc
를 실행해 새로운 TypeScript 파일의 타입을 검사한다.
- npm
- Yarn
npx tsc
yarn tsc
타입스크립트 대신 자바스크립트 사용하기
React Native는 새로운 애플리케이션을 기본적으로 타입스크립트로 설정한다. 하지만 여전히 자바스크립트를 사용할 수 있다. .jsx
확장자를 가진 파일은 타입스크립트가 아닌 자바스크립트로 처리되며, 타입 검사가 이루어지지 않는다. 자바스크립트 모듈은 타입스크립트 모듈에서 가져올 수 있으며, 그 반대도 가능하다.
TypeScript와 React Native의 동작 방식
기본적으로 TypeScript 소스 코드는 번들링 과정에서 Babel에 의해 변환된다. TypeScript 컴파일러는 타입 검사만을 위해 사용하는 것을 권장한다. 이는 새로 생성된 애플리케이션에서 tsc
의 기본 동작이다. 기존의 TypeScript 코드를 React Native로 포팅하는 경우, TypeScript 대신 Babel을 사용할 때 주의해야 할 몇 가지 사항이 있다.
React Native + TypeScript 예제 살펴보기
React 컴포넌트의 Props와 State에 인터페이스를 제공하려면 React.Component<Props, State>
를 사용한다. 이렇게 하면 JSX에서 해당 컴포넌트를 작업할 때 타입 검사와 에디터 자동 완성 기능을 활용할 수 있다.
import React from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';
export type Props = {
name: string;
baseEnthusiasmLevel?: number;
};
const Hello: React.FC<Props> = ({
name,
baseEnthusiasmLevel = 0,
}) => {
const [enthusiasmLevel, setEnthusiasmLevel] = React.useState(
baseEnthusiasmLevel,
);
const onIncrement = () =>
setEnthusiasmLevel(enthusiasmLevel + 1);
const onDecrement = () =>
setEnthusiasmLevel(
enthusiasmLevel > 0 ? enthusiasmLevel - 1 : 0,
);
const getExclamationMarks = (numChars: number) =>
numChars > 0 ? Array(numChars + 1).join('!') : '';
return (
<View style={styles.container}>
<Text style={styles.greeting}>
Hello {name}
{getExclamationMarks(enthusiasmLevel)}
</Text>
<View>
<Button
title="Increase enthusiasm"
accessibilityLabel="increment"
onPress={onIncrement}
color="blue"
/>
<Button
title="Decrease enthusiasm"
accessibilityLabel="decrement"
onPress={onDecrement}
color="red"
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
greeting: {
fontSize: 20,
fontWeight: 'bold',
margin: 16,
},
});
export default Hello;
더 자세한 문법은 TypeScript playground에서 확인할 수 있다.
유용한 정보를 찾을 수 있는 곳
- TypeScript 핸드북
- TypeScript 관련 React 공식 문서
- React + TypeScript 치트시트에는 React와 TypeScript를 함께 사용하는 방법에 대한 유용한 개요가 포함되어 있다
커스텀 경로 별칭을 TypeScript와 함께 사용하기
TypeScript에서 커스텀 경로 별칭을 사용하려면 Babel과 TypeScript 모두에서 경로 별칭이 작동하도록 설정해야 한다. 방법은 다음과 같다:
tsconfig.json
을 수정해 커스텀 경로 매핑을 설정한다.src
루트의 모든 파일을 경로 참조 없이 사용할 수 있게 하고,tests/File.tsx
를 통해 테스트 파일에 접근할 수 있도록 한다:
{
- "extends": "@tsconfig/react-native/tsconfig.json"
+ "extends": "@tsconfig/react-native/tsconfig.json",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "*": ["src/*"],
+ "tests": ["tests/*"],
+ "@components/*": ["src/components/*"],
+ },
+ }
}
- 프로젝트에 개발 패키지로
babel-plugin-module-resolver
을 추가한다:
- npm
- Yarn
npm install --save-dev babel-plugin-module-resolver
yarn add --dev babel-plugin-module-resolver
- 마지막으로
babel.config.js
를 설정한다 (babel.config.js
의 문법은tsconfig.json
과 다르다는 점에 유의한다):
{
presets: ['module:metro-react-native-babel-preset'],
+ plugins: [
+ [
+ 'module-resolver',
+ {
+ root: ['./src'],
+ extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
+ alias: {
+ tests: ['./tests/'],
+ "@components": "./src/components",
+ }
+ }
+ ]
+ ]
}