Next.js と TypeScript で、オプショナルチェーン(?.)を活用する

TwitterFacebookHatena

TL;DR

このページでは、"オプショナルチェーン(?.)"の実装方法について解説しますね。一言でいうとオプショナルチェーンとは、あるオブジェクトが undefined または null の場合でもエラーを発生させずに undefined を返すための便利な機能です。

開発環境 バージョン
Next.js 13.4.4
TypeScript 5.0.4
Emotion 11.11.0
React 18.2.0

オプショナルチェーンとは?

JavaScript と TypeScript の世界では、一部のオブジェクトが undefined または null になる可能性があります。これは頻繁に発生する場面で、例えば API からのレスポンスが想定した形式ではなかったり、ユーザー入力が想定外だったりすると起こり得ます。そのため、開発者は常に null チェックや undefined チェックを行わなければなりません。

しかし、そのようなチェックが多くなると、コードは読みにくく、保守しにくくなります。ここでオプショナルチェーンの出番です。オプショナルチェーンを使えば、安全にプロパティにアクセスし、その値が存在しない場合はただちに undefined を返すことができます。

let user = {
  name: 'Taro',
  address: {
    zip: '123-4567',
    prefecture: 'Tokyo',
    city: null,
  },
}

console.log(user?.address?.city) // null
console.log(user?.address?.street?.name) // undefined

ここでは、user.address.city の値は null で、user.address.street.name は存在しないプロパティにアクセスしようとしていますが、エラーを出すことなく undefined を返します。

Next.js で、オプショナルチェーンを活用

Next.js のコンテクストでは、オプショナルチェーンはデータの取り扱いを大いに簡略化します。以下にその一例を示します。

/components/UserProfile.tsx

import { useEffect, useState } from 'react'

type User = {
  id: number
  name: string
  address?: {
    zip: string
    prefecture: string
    city?: string
  }
}

const UserProfile = () => {
  const [user, setUser] = useState<User | null>(null)

  useEffect(() => {
    fetchUser().then((user) => setUser(user))
  }, [])

  return (
    <div>
      <p>{user?.name}</p>
      <p>{user?.address?.zip}</p>
      <p>{user?.address?.city}</p>
    </div>
  )
}

async function fetchUser(): Promise<User> {
  // ここで実際のAPIリクエストを行います。
}

export default UserProfile

このコンポーネントでは、API から取得したユーザー情報を表示しています。しかし、すべてのユーザーが address や city を持っているわけではありません。オプショナルチェーンを使用することで、それらのプロパティが存在しない場合でもエラーを発生させずに安全にコードを実行することができます。

オプショナルチェーンと Nullish Coalescing

オプショナルチェーンの強力なパートナーとして、「Nullish Coalescing(??)」があります。これは、左側の値が null または undefined の場合に、右側の値を返す演算子です。これにより、値が存在しない場合のデフォルト値を簡単に指定することができます。

const UserProfile = ({ user }: { user: User | null }) => (
  <div>
    <p>{user?.name ?? '名前がありません'}</p>
    <p>{user?.address?.zip ?? '郵便番号がありません'}</p>
    <p>{user?.address?.city ?? '市区町村がありません'}</p>
  </div>
)

ここでは、ユーザーの名前、郵便番号、市区町村が存在しない場合、代替のメッセージを表示しています。これにより、アプリケーションはユーザーフレンドリーでありながらも、安全にデータを操作することができます。

TypeScript でのオプショナルチェーンの型推論

TypeScript の威力を最大限に引き出すためには、適切な型定義が欠かせません。オプショナルチェーンと組み合わせることで、より安全で予測可能なコードを書くことが可能になります。

type User = {
  id: number
  name: string
  address?: {
    zip: string
    prefecture: string
    city?: string
  }
}

const UserProfile = ({ user }: { user: User | null }) => (
  <div>
    <p>{user?.name}</p>
    <p>{user?.address?.zip}</p>
    <p>{user?.address?.city}</p>
  </div>
)

この例では、User 型の address フィールドがオプショナルであり、さらにその中の city フィールドもオプショナルであることを示しています。これにより、TypeScript はこのフィールドが存在しない可能性があることを認識し、それに対応するコード(オプショナルチェーン)を書くように促します。

以上、オプショナルチェーンを利用した Next.js と TypeScript のコード実装について詳しく解説しました。この特性を使うことで、存在しない可能性のあるプロパティに安全にアクセスし、より堅牢なアプリケーションを構築することができます。さらに、Nullish Coalescing と組み合わせることで、デフォルト値を簡単に指定できます。

Next.js と TypeScript で、オプショナルチェーン(?.)を活用する