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
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.Component<Props, State>
を介して React コンポーネントの 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 ハンドブック
- React の TypeScript に関するドキュメント
- 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",
+ }
+ }
+ ]
+ ]
}