こんにちは。今回は、typescriptについて初心者エンジニアに向けて、reactとの組み合わせでより安全なwebアプリケーションを構築する方法について解説します。
reactとtypescriptの組み合わせのメリットとは?
reactは、仮想domを使用したコンポーネントベースのビューライブラリであり、ui開発をシンプルかつ効率的に行うことができます。一方、typescriptはjavascriptの静的型検査を行うためのプログラミング言語であり、コードの品質と保守性を高めることができます。reactとtypescriptを組み合わせることで、以下のようなメリットが得られます。
- コンポーネントの型付けによるコードの品質向上
- 型の不一致を防止することによるバグの予防
- ドキュメンテーションの削減によるコードの可読性の向上
- 安全性の向上による生産性の向上
typescriptを使ったreactコンポーネントの型付けの方法
typescriptを使うことで、reactのコンポーネントの入力(props)と出力(state)に型を定義することができます。以下に、コンポーネントの型定義と使用例を示します。
interface props {
  name: string;
  age: number;
}
const hello: react.fc<props> = ({ name, age }) => {
  return (
    <div>
      <p>hello, {name}!</p>
      <p>you are {age} years old.</p>
    </div>
  );
};
// 使用例
<hello name="john smith" age={30} />上記の例では、propsという名前のインターフェースを定義し、そのプロパティとしてnameとageを宣言しています。また、react.fc
react hooksの型安全な使用方法について
react hooksは、reactの状態管理やライフサイクル等をシンプルに実装できる機能です。typescriptを使ってreact hooksを安全に使用するためには、以下の点に注意が必要です。
- usestateフックの型定義
- 関数コンポーネントに型を適用する
- カスタムフックに型を適用する
以下に、その例を示します。
interface todo {
  id: number;
  title: string;
  completed: boolean;
}
const todos: react.fc = () => {
  const [todos, settodos] = usestate<todo[]>([]); // 1.
  const fetchdata = usecallback(async () => {
    const result = await fetch('https://jsonplaceholder.typicode.com/todos');
    const data = await result.json();
    settodos(data);
  }, []);
  useeffect(() => {
    fetchdata();
  }, [fetchdata]);
  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
};上記の例では、usestateにジェネリック型を指定することで、todosの型をtodo[]に定義しています。また、react.fcを使用することで、関数コンポーネントに型を適用しています。さらに、usecallbackおよびuseeffectにも型を指定しています。このように、react hooksを使う場合も、typescriptによって安全性を高めることができます。
reduxとtypescriptを組み合わせたアプリケーションの開発方法
reduxは、アプリケーション内の状態を管理するためのライブラリであり、typescriptと組み合わせることで、型安全なコードを書くことができます。以下に、reduxとtypescriptを組み合わせたアプリケーションを開発する際のポイントを示します。
- アクションの型定義
- ストアの型定義
- レデューサーの型定義
以下に、その例を示します。
// アクションの型定義
interface incrementcounteraction {
  type: 'increment_counter';
  payload: number;
}
interface decrementcounteraction {
  type: 'decrement_counter';
  payload: number;
}
type counteraction = incrementcounteraction | decrementcounteraction;
// ストアの型定義
interface counterstate {
  count: number;
}
const initialstate: counterstate = {
  count: 0,
};
// レデューサーの型定義
const reducer: reducer<counterstate, counteraction> = (
  state = initialstate,
  action
) => {
  switch (action.type) {
    case 'increment_counter':
      return { ...state, count: state.count + action.payload };
    case 'decrement_counter':
      return { ...state, count: state.count - action.payload };
    default:
      return state;
  }
};
const store = createstore(reducer);
const counter: react.fc = () => {
  const { count } = useselector((state: counterstate) => state); // ストアから状態を取得
  const dispatch = usedispatch(); // dispatcherの取得
  return (
    <div>
      <p>{count}</p>
      <button onclick={() => dispatch({ type: 'increment_counter', payload: 1 })}>
        +
      </button>
      <button onclick={() => dispatch({ type: 'decrement_counter', payload: 1 })}>
        -
      </button>
    </div>
  );
};上記の例では、アクション、ストア、レデューサーにそれぞれ型を定義しています。また、useselectorでストアからの状態取得時に、状態の型を指定し、usedispatchでdispatcherを取得しています。このように、reduxとtypescriptを組み合わせることで、アプリケーションの安全性向上が図れます。
reactとtypescriptでのテストの書き方と、テストカバレッジの向上について
テストは、アプリケーションにおける品質と信頼性を向上させるために欠かせないものです。reactとtypescriptを組み合わせたアプリケーションのテストの書き方と、テストカバレッジの向上について紹介します。
- jestとenzymeを使ったテストの記述方法
- カバレッジレポートの取得方法
- モックを使用したテストの方法
以下に、その例を示します。
describe('counter', () => {
  it('increments the count when the plus button is clicked', () => {
    const wrapper = mount(<counter />);
    const plusbutton = wrapper.find('button').at(0);
    plusbutton.simulate('click');
    expect(wrapper.find('p').text()).toequal('1');
  });
  it('decrements the count when the minus button is clicked', () => {
    const wrapper = mount(<counter />);
    const minusbutton = wrapper.find('button').at(1);
    minusbutton.simulate('click');
    expect(wrapper.find('p').text()).toequal('-1');
  });
});
// カバレッジレポートの取得方法
// package.json
{
  "scripts": {
    "test": "jest",
    "test-coverage": "jest --coverage"
  }
}
$ yarn test-coverage
// モックを使用したテストの方法
import * as react from 'react';
import { shallow } from 'enzyme';
import { fetchuser } from './api'; // apiのモック化
jest.mock('./api', () => {
  return {
    fetchuser: jest.fn(),
  };
});
describe('user', () => {
  it('successfully fetches the user', async () => {
    const user = { id: 1, name: 'john smith' };
    fetchuser.mockresolvedvalueonce(user); // apiのレスポンスをモック化
    const wrapper = shallow(<user />);
    await wrapper.instance().componentdidmount(); // componentdidmountを呼び出し
    expect(wrapper.state('user')).toequal(user);
  });
});上記の例では、jestとenzymeを使ったテストの記述方法、カバレッジレポートの取得方法、モックを使用したテストの方法を解説しています。これらの方法を使用することで、reactとtypescriptでのテストによって、より安全で信頼性の高いアプリケーションを構築することができます。
以上、reactとtypescriptを組み合わせてより安全なwebアプリケーションを構築する方法について解説しました。初心者エンジニアでも理解できるように、具体的なコード例を交えながら紹介しました。typescriptを使えば、reactアプリケーションの安全性と信頼性を向上させることができるので、ぜひ活用してみてください。参考になるブログ記事は、こちらやこちらなどがあります。
typescript関連のまとめ

オンラインスクールを講師として活用する!

