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 typescript @react-native/typescript-config @types/jest @types/react @types/react-test-renderer
yarn add --dev typescript @react-native/typescript-config @types/jest @types/react @types/react-test-renderer
このコマンドは、各依存関係の最新バージョンを追加します。バージョンは、プロジェクトで使用されている既存のパッケージと一致するように変更する必要があるかもしれません。React Native Upgrade Helperのようなツールを使用して、React Nativeが出荷するバージョンを確認できます。
- TypeScriptの設定ファイルを追加します。プロジェクトのルートに
tsconfig.json
を作成します。
{
"extends": "@react-native/typescript-config"
}
- JavaScriptファイルの名前を
*.tsx
に変更します。
./index.js
のエントリーポイントファイルはそのままにしておくべきです。そうしないと、本番ビルドのバンドル時に問題が発生する可能性があります。
tsc
を実行して、新しいTypeScriptファイルの型チェックを行います。
- npm
- Yarn
npx tsc
yarn tsc
TypeScriptの代わりにJavaScriptを使用する
React Nativeは新しいアプリケーションではデフォルトでTypeScriptを使用しますが、JavaScriptも引き続き使用できます。.jsx
拡張子を持つファイルはTypeScriptではなくJavaScriptとして扱われ、型チェックは行われません。JavaScriptモジュールはTypeScriptモジュールからインポートでき、その逆も可能です。
TypeScriptとReact Nativeの仕組み
デフォルトでは、TypeScriptのソースはバンドル時にBabelによって変換されます。TypeScriptコンパイラは型チェックにのみ使用することをお勧めします。これは、新しく作成されたアプリケーションでのtsc
のデフォルトの動作です。既存のTypeScriptコードをReact Nativeに移植する場合、TypeScriptの代わりにBabelを使用するには1つか2つの注意点があります。
React Native + TypeScriptはどのように見えるか
ReactコンポーネントのPropsとStateのインターフェースをReact.Component<Props, State>
を介して提供できます。これにより、JSXでそのコンポーネントを扱う際に型チェックとエディタの自動補完が提供されます。
import {useState} from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';
export type Props = {
name: string;
baseEnthusiasmLevel?: number;
};
function Hello({name, baseEnthusiasmLevel = 0}: Props) {
const [enthusiasmLevel, setEnthusiasmLevel] = 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 Handbook
- ReactのTypeScriptに関するドキュメント
- React + TypeScript Cheatsheetsには、TypeScriptでReactを使用する方法に関する良い概要があります。
TypeScriptでカスタムパスエイリアスを使用する
TypeScriptでカスタムパスエイリアスを使用するには、BabelとTypeScriptの両方でパスエイリアスが機能するように設定する必要があります。以下にその方法を示します。
tsconfig.json
を編集して、カスタムパスマッピングを設定します。src
のルートにあるものは先行パス参照なしで利用できるようにし、テストファイルはtests/File.tsx
を使用してアクセスできるようにします。
{
- "extends": "@react-native/typescript-config"
+ "extends": "@react-native/typescript-config",
+ "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",
+ }
+ }
+ ]
+ ]
}