[RN] React Nativeで型定義もやりたい!jsx→tsxへの設定方法!

TypeScript React Native Starter

Microsoft/TypeScript-React-Native-Starter: A starter template for TypeScript and React Native with a detailed README describing how to use the two together.

このページは上記リンクの意訳になります。

注意
一部、TypeScript対応できていないライブラリもあります。今の所、react-nativeやexpoのTypeScript化には妥協とおおらかな心が必要です。

前提条件

React NativeのWebサイトの指示に従い、TypeScriptなしで簡単なReact Nativeアプリを実行できることをデバイスやエミュレータで確認する必要があります。

もちろん、Node.jsNPM, and Yarnなどが必要。

TypeScriptの追加

次に、TypeScriptをプロジェクトに追加します。こんな事します。

  • プロジェクトにTypeScriptを追加する
  • あなたのプロジェクトにReact Native TypeScript Transformerを追加する
  • 空のTypeScript設定ファイルを初期化する
  • 設定する空のReactNativeTypeScriptTransformer設定ファイルを追加する
  • React NativeとReactにタイプを追加する

さて、これらを実行してみましょう。

yarn add --dev typescript
yarn add --dev react-native-typescript-transformer
yarn tsc --init --pretty --jsx react
touch rn-cli.config.js
yarn add --dev @types/react @types/react-native

tsconfig.jsonファイルには、TypeScriptコンパイルのすべての設定が含まれています。上記のコマンドで作成されたデフォルト値は概ね問題ありませんが、ファイルを開き、次の行のコメントを外してください:

{
  ...
  // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
  ...
}

rn-cli.config.jsには、React Native TypeScript Transformerの設定が含まれています。それを開き、以下を追加してください:

module.exports = {
  getTransformModulePath() {
    return require.resolve("react-native-typescript-transformer");
  },
  getSourceExts() {
    return ["ts", "tsx"];
  }
};

TypeScriptへの移行

生成されたApp.jsファイルと__tests__ / App.jsファイルの名前をApp.tsxに変更します。 index.js.js拡張子を使用する必要があります。新しいファイルはすべて.tsx拡張子(またはファイルにJSXが含まれていない場合は.ts)を使用する必要があります。

あなたがアプリケーションを実行しようとすると、オブジェクトプロトタイプがオブジェクトかnullだけかもしれないというエラーが出ます(object prototype may only be an object or null)これは、Reactのデフォルトエクスポートと同じ行の名前付きエクスポートをインポートできなかったことが原因です。 App.tsxを開き、ファイルの先頭にインポートを変更します。

↕️おそらくReactの話。。。

-import React, { Component } from 'react';
+import React from 'react'
+import { Component } from 'react';

このうちのいくつかは、BabelとTypeScriptがCommonJSモジュールとどのように相互運用するかという違いがあります。将来的には、2人は同じ行動で安定するでしょう。

そしてExpoにもtsを使う設定をします。

app.jsonに次の設定を追加します。

"packagerOpts": {
  "sourceExts": ["ts", "tsx"],
  "transformer": "node_modules/react-native-typescript-transformer/index.js"
}

この時点で、React Nativeアプリを実行できるはずです。

TypeScriptテストインフラストラクチャの追加

Jestを使用しているので、devDependenciesにts-jestを追加したいと思うでしょう。

yarn add --dev ts-jest

次に、package.jsonを開き、jestフィールドに設定を追加します。

"jest": {
・・・・
  "moduleFileExtensions": [
    "ts",
    "tsx",
    "js"
  ],
  "transform": {
    "^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
    "\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
  },
  "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
  "testPathIgnorePatterns": [
    "\\.snap$",
    "<rootDir>/node_modules/"
  ],
  "cacheDirectory": ".jest/cache"
}

これによりJestはts-jest.ts.tsxファイルを実行します。

型宣言の依存関係のインストール

TypeScriptで最高のエクスペリエンスを得るには、型チェッカーが依存関係の形とAPIを理解しる必要があります。一部のライブラリは、基本となるJavaScriptの形状を記述できる.d.tsファイル(「型付き宣言」または「型定義」ファイルとも呼ばれます)でパッケージを公開します。他のライブラリについては、適切なパッケージを
@types/npmスコープに明示的にインストールする必要があります。例えば、ここではJest、React、React Native、React Test Rendererの型が必要です。

yarn add --dev @types/jest @types/react @types/react-native @types/react-test-renderer

私たちは、このパッケージをnpmのライブラリとして公開していないので、これらの宣言ファイルパッケージを開発者の依存関係に保存しました。もしそうだったら、それらのいくつかを通常の依存関係として追加する必要があります。

.d.tsファイルを入手する方法については、こちらをご覧ください。

その他のファイルを無視する

あなたのソース管理については、.jestフォルダーの無視の設定をします。 gitを使用している場合は、.gitignoreファイルにエントリを追加するだけです。

# Jest
#
.jest/

チェックポイントとして、ファイルをバージョン管理にコミットすることを検討してください。

git init
git add .gitignore # import to do this first, to ignore our files
git add .
git commit -am "Initial commit."

コンポーネントの追加

これで、アプリにコンポーネントを追加できるようになりました。 Hello.tsxコンポーネントを作成しましょう。 componentsディレクトリを作成し、次の例を追加します。

// components/Hello.tsx
import React from "react"
import { Button, StyleSheet, Text, View } from "react-native"

export interface Props {
  name: string
  enthusiasmLevel?: number
  onIncrement?: () => void
  onDecrement?: () => void
}

interface State {
  enthusiasmLevel: number
}

export class Hello extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props)

    if ((props.enthusiasmLevel || 0) <= 0) {
      throw new Error("You could be a little more enthusiastic. :D")
    }

    this.state = {
      enthusiasmLevel: props.enthusiasmLevel || 1
    }
  }

  onIncrement = () => this.setState({ enthusiasmLevel: this.state.enthusiasmLevel + 1 });
  onDecrement = () => this.setState({ enthusiasmLevel: this.state.enthusiasmLevel - 1 });
  getExclamationMarks = (numChars: number) => Array(numChars + 1).join("!")

  render() {
    return (
      <View style={styles.root}>
        <Text style={styles.greeting}>
          Hello {this.props.name + this.getExclamationMarks(this.state.enthusiasmLevel)}
        </Text>

        <View style={styles.buttons}>
          <View style={styles.button}>
            <Button
              title="-"
              onPress={this.onDecrement}
              accessibilityLabel="decrement"
              color="red"
            />
          </View>

          <View style={styles.button}>
            <Button
              title="+"
              onPress={this.onIncrement}
              accessibilityLabel="increment"
              color="blue"
            />
          </View>
        </View>
      </View>
    )
  }
}

// styles

const styles = StyleSheet.create({
  root: {
    alignItems: "center",
    alignSelf: "center"
  },
  buttons: {
    flexDirection: "row",
    minHeight: 70,
    alignItems: "stretch",
    alignSelf: "center",
    borderWidth: 5
  },
  button: {
    flex: 1,
    paddingVertical: 0
  },
  greeting: {
    color: "#999",
    fontWeight: "bold"
  }
})

コンポーネントテストの追加

コンポーネントが完成したので、テストしてみましょう。

すでにテストランナーとしてJestをインストールしています。コンポーネントのスナップショットテストを作成し、スナップショットテストに必要なアドオンを追加しましょう:

yarn add --dev react-addons-test-utils

次に、componentsディレクトリに__tests__フォルダを作成し、Hello.tsxのテストを追加します。

// components/__tests__/Hello.tsx
import React from 'react'
import renderer from 'react-test-renderer'

import { Hello } from "../Hello"

it("renders correctly with defaults", () => {
  const button = renderer.create(<Hello name="World" enthusiasmLevel={1} />).toJSON()
  expect(button).toMatchSnapshot()
})

初めてテストを実行すると、レンダリングされたコンポーネントのスナップショットが作成され、components/__tests__/__snapshots__/Hello.tsx.snapファイルに格納されます。コンポーネントを変更するときは、スナップショットを更新し、意図しない変更があるかどうかを確認する必要があります。 Reactネイティブコンポーネントのテストの詳細はこちらで読むことができます。

Next Steps

React TypeScriptチュートリアルでは、Reduxでの状態管理などのトピックについても説明しています。 Reactネイティブアプリを書くときにも適用することができます。

さらに、Web上のReactとReact Nativeの両方をサポートするTypeScriptで完全に記述されたコンポーネントライブラリを探している場合は、ReactXPを見ることができます。

役に立つリソース

ネイティブの作成ネイティブTypeScriptは、TypeScriptを使用するCreate ReactネイティブAppのポートです。
React Native Template TypeScriptは、クイックスタートのためのクリーンでシンプルなテンプレートです。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする