🔰

なぜ、ReactやNext.jsプロジェクトで TypeScript を使用するの?

2024/03/31に公開

フロントエンドプロジェクトの開発にはプログラミング言語の選択が重要です。
近年、保守性、再利用性、文書化、生産性の面でメリットがあるため、フロントエンドプロジェクトで TypeScriptが使用されることが増えています。

この記事では、ReactNext.jsの例を使用して、TypeScriptでフロントエンドプロジェクトを開発することをあくまでも主観的にお勧めする6つの理由を説明します。

そもそもTypeScriptってなに?

TypeScriptは、Microsoftによって開発されたオープンソースプログラミング言語です。これは、オプションの静的型システムを言語に追加するJavaScriptのスーパーセットです。変数の型が実行時に動的に決定されるJavaScriptとは異なり、TypeScriptを使用すると、開発者は開発段階で変数の型を指定できます。

多くの開発者は、特にReactNext.jsなどの人気のあるフレームワークで、フロントエンド開発にTypeScriptを使用しています。TypeScriptの高度な機能と静的型付けシステムのおかげで、より堅牢で信頼性の高いフロントエンドアプリケーションを作成できます。

お勧めする6つの理由

1. バグの軽減

フロントエンドプロジェクトにTypeScriptを選択する最初の理由の1つは、型を使用するバグを減らすことです。変数の型が動的に決定されるJavaScriptとは異なり、TypeScriptでは開発者が開発段階で変数の型を指定できます。

TypeScriptを使用してReactコンポーネントのpropsを入力する例を次に示します。

type Props = {
  name: string
  age: number
}

const MyComponent = ({ name, age }: Props) => {
  return (
    <div>
      <p>Nom: {name}</p>
      <p>Âge: {age}</p>
    </div>
  )
}

2. 簡素化されたリファクタリング

TypeScriptを使用すると、存在しないプロパティにアクセスしようとしたり、関数に間違った引数を渡したり、間違った型の値を使用しようとした場合に型システムが警告を発するため、安心して変更を加えることができます。

具体的な例として、Next.jsプロジェクトにタスクのリストを表示するReactコンポーネントがあるとします。コンポーネントはJavaScriptでは次のようになります。

// TaskList.js
import React from 'react'

const TaskList = ({ tasks }) => {
  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>{task.text}</li>
      ))}
    </ul>
  )
}

export default TaskList

ここで、タスクを完了としてマークする機能を追加するとします。
まず、TypeScriptではタスクのタイプを定義することから始めることができます。

// Task.ts
type Task = {
  id: number
  text: string
  completed: boolean
}

次に、このタイプを使用するようにコンポーネントを更新し、各タスクにチェックボックスを追加できます。

// TaskList.tsx
import React from 'react'

type Task = {
  id: number
  text: string
  completed: boolean
}

type TaskListProps = {
  tasks: Task[]
}

const TaskList: React.FC<TaskListProps> = ({ tasks }) => {
  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>
          <input type="checkbox" checked={task.completed} />
          <span>{task.text}</span>
        </li>
      ))}
    </ul>
  )
}

export default TaskList

TypeScriptを使用すると、型システムによってタスクプロパティへのすべての参照が正しいことが保証されるため、安心して新しい機能を追加できます。

誤って存在しないプロパティにアクセスしようとしたり、関数に間違った型を渡そうとした場合、TypeScriptは開発段階で警告を表示するため、コードをテストする前にエラーを修正できます。

3. コードの可読性の向上

TypeScriptでは、変数、コンポーネントのプロパティ、関数の戻り値の型を明示的に定義することで、開発者にとってコードがより理解しやすくなります。たとえば、Reactコンポーネントでは、propタイプを定義すると、このコンポーネントがどのようなデータを期待しているかをすぐに理解できます。

たとえば、Next.jsでは、APIから取得するデータの型を定義するときに、TypeScriptを使用してこれらの型を指定できるため、コードが他のチームメンバーにとってより理解しやすくなります。

APIから取得したデータをTypeScriptを使用してNext.jsに入力する例を次に示します。

type Post = {
  id: number
  title: string
  body: string
}

const fetchPost = async (postId: number): Promise<Post> => {
  const response = await fetch("https://api.example.com/posts/" + postId)
  return await response.json()
}

4. 文書化

TypeScriptは、静的型システムを通じてコード内ドキュメントを提供します。型アノテーションとインターフェイスを使用すると、データ構造、コンポーネントの小道具、関数の型などを明確に記述することができます。

これにより、他の開発者 (または後日自分自身) が、コードを詳しく調べなくても、コードがどのように機能するかをすぐに理解できるようになります。

例1: 基本的な型アノテーション

const greet = (name: string): string => {
  return `Hello, ${name}!`
}

const userName: string = 'Alice'
console.log(greet(userName))

この例では、greet関数とuserName変数にstring型のアノテーションをつけています。これにより、greet関数は文字列を引数にとり、文字列を返すこと、userName変数は文字列型であることが明確になります。

例2: インターフェイスを使ったオブジェクトの型定義

interface User {
  name: string
  age: number
}

const printUser = (user: User) => {
  console.log(`Name: ${user.name}, Age: ${user.age}`)
}

printUser({ name: 'Bob', age: 25 })

この例では、Userインターフェイスを定義しています。Userはnameとageプロパティを持つオブジェクトの型として機能します。printUser関数は、このインターフェイスに沿ったオブジェクトを引数として受け取ります。これにより、任意のオブジェクトがUserインターフェイスの要件を満たしているかどうかが一目でわかります。

5. 生産性の向上

TypeScriptは、静的型付けシステムを使用して、開発環境におけるオートコンプリートとドキュメントのサポートを強化します。

たとえば、Visual Studio CodeWebstormなどのIDEをTypeScriptで使用する場合、変数名のオートコンプリート、Reactコンポーネントのメソッドとプロパティ、型に関するコンテキスト情報などの高度な機能の恩恵を受けます。これにより、開発者はより迅速かつ効率的にコードを作成できるようになります。

6. JavaScript とのシームレスな統合

TypeScriptJavaScriptと互換性があるため、既存のJavaScriptコードを TypeScriptプロジェクトに簡単に統合でき、開発者はスムーズに移行できます。

これはTypeScriptの長所でもあり、短所でもあります。コードを入力しなくても、プロジェクトに TypeScriptをインストールできます。こうすることで、既存のプロジェクトに実装していくことができます。

まとめ

ReactNext.jsを使用したフロントエンドプロジェクトでJavaScriptではなくTypeScriptを使用すると、静的型付けによるセキュリティの向上、オートコンプリートとドキュメント化による生産性の向上、メンテナンスの容易化、コラボレーションの向上など、多くの利点があります。

これらの利点を考慮することで、開発者は情報に基づいた意思決定を行い、ニーズに最も適したプログラミング言語を選択できます。

参考資料

Discussion