[React Native] 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 추가하기

npm install -D @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 엔트리 포인트 파일은 그대로 두어야 합니다. 그렇지 않으면 프로덕션 빌드를 번들링할 때 문제가 발생할 수 있습니다.

새 typescript 파일을 타입 체크하려면 tsc를 실행합니다.

npx tsc

javascript 대신 typescript 사용하기

react native는 기본적으로 새로운 애플리케이션을 typescript로 설정하지만 javascript도 사용할 수 있습니다. .jsx확장자를 가진 파일은 typescript 대신 javascript로 처리되며, 타입체크를 받지 않습니다. javascript 모듈은 여전히 typescript 모듈로 가져올 수 있으며 그 반대도 가능합니다.

typescript와 react native의 작동 방식

기본적으로 typescript 소스는 번들링 중 babel에 의해 변환됩니다. typescript 컴파일러는 타입 체크에만 사용하는 것을 권장합니다. 이는 새로 생성된 애플리케이션의 기본 동작입니다. 기존 typescript 코드를 react native로 포팅할 경우, babel 대신 typescript 사용하는 데 몇 가지 주의사항이 있을 수 있습니다.

react native + typescript 예제

import React from "react";
import { Button, StyleSheet, Text, View } from "react-native";

export type Props = {
    name: string;
    baseAge?: number;
}

const Home: React.FC<Props> = ({
    name,
    baseAge = 0
}) => {
    const [age, setAge] = React.useState(baseAge)

    const onIncrement = () => {
        setAge(age+1);
    }

    const onDecrement = () => {
        setAge(age-1);
    }

    return (
        <View>
            <Text style={styles.text}>
                name: {name}
                age: {age}
            </Text>
            <View>
                <Button title="increase age" onPress={onIncrement} />
                <Button title="decrease age" onPress={onDecrement} />
            </View>
        </View>
    )
}

const styles = StyleSheet.create({
    text: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
});

export default Home;

타입스크립트에서 사용자 정의 경로 별칭 사용하기

타입스크립트에서 사용자 정의 경로 별칭을 사용하려면 babel과 typescript 모두에서 경로 별칭을 설정해야 합니다. 방법은 다음과 같습니다.

tsconfig.json을 편집하여 사용자 정의 경로 매핑을 추가합니다. src의 루트에 있는 모든 항목을 참조 경로 없이 사용할 수 있도록 설정하고 테스트 파일을 tests/File.tsx로 접근할 수 있도록 합니다.

{
  "extends": "@tsconfig/react-native/tsconfig.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["src/*"],
      "tests": ["tests/*"],
      "@components/*": ["src/components/*"]
    }
  }
}
npm install --save-dev babel-plugin-module-resolver

babel.config.js에도 구성을 해야합니다.

module.exports = {
  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"
        }
      }
    ]
  ]
}