コンテンツにスキップ
NextAuth.js v4 からの移行ですか? 移行ガイドをご覧ください.
はじめにTypeScript

TypeScript

Auth.js はタイプセーフティにコミットしており、TypeScript で記述され、100% タイプセーフです。プロジェクトで使用する独自の型定義が付属しています。

TypeScript を使用していなくても、VS Code などの IDE はこれを認識して、より優れた開発エクスペリエンスを提供します。入力中に、特定のオブジェクト/関数の外観に関する提案、ドキュメント、例、その他の貴重なリソースへのリンクが表示される場合があります。

理念

Auth.js リソースを拡張する場合に、アプリケーション全体で型付けするための主な手法として、ジェネリクスではなくモジュール拡張を選択しました。

なぜジェネリクスを使用しないのですか?

サブモジュール間で共有されるインターフェースは、ジェネリクスとして Auth.js ライブラリ関数に渡されません。

これらの型が使用されるたびに、関数は常にこれらの形式を返すことを期待します。ジェネリクスを使用すると、ある場所で型をオーバーライドできますが、別の場所ではオーバーライドできないため、型が実装と同期しなくなります。

モジュール拡張では、型を一度定義すると、常に期待どおりの場所にあることが保証されます。

モジュール拡張

Auth.js ライブラリには、サブモジュールや異なる Auth.js ライブラリ間で共有される特定のインターフェースが付属しています(例:next-auth@auth/prisma-adapter@auth/coreの型に依存します)。

このようなインターフェースの良い例は、SessionまたはUserです。TypeScript のモジュール拡張を使用して、これらの型を拡張し、Auth.js 全体に独自の プロパティを追加することができます。いたるところにジェネリックを渡す必要はありません。

例として、Sessionの拡張を見てみましょう。

auth.ts
import NextAuth, { type DefaultSession } from "next-auth"
 
declare module "next-auth" {
  /**
   * Returned by `auth`, `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
   */
  interface Session {
    user: {
      /** The user's postal address. */
      address: string
      /**
       * By default, TypeScript merges new interface properties and overwrites existing ones.
       * In this case, the default session user properties will be overwritten,
       * with the new ones defined above. To keep the default session user properties,
       * you need to add them back into the newly declared interface.
       */
    } & DefaultSession["user"]
  }
}
 
export const { auth, handlers } = NextAuth({
  callbacks: {
    session({ session, token, user }) {
      // `session.user.address` is now a valid property, and will be type-checked
      // in places like `useSession().data.user` or `auth().user`
      return {
        ...session,
        user: {
          ...session.user,
          address: user.address,
        },
      }
    },
  },
})

モジュール拡張は特定のインターフェースに限定されません。定義したinterfaceはすべて拡張できます。ユースケースに基づいてオーバーライドしたい一般的なインターフェースをいくつか紹介します。

types.d.ts
declare module "next-auth" {
  /**
   * The shape of the user object returned in the OAuth providers' `profile` callback,
   * or the second parameter of the `session` callback, when using a database.
   */
  interface User {}
  /**
   * The shape of the account object returned in the OAuth providers' `account` callback,
   * Usually contains information about the provider being used, like OAuth tokens (`access_token`, etc).
   */
  interface Account {}
 
  /**
   * Returned by `useSession`, `auth`, contains information about the active session.
   */
  interface Session {}
}
 
// The `JWT` interface can be found in the `next-auth/jwt` submodule
import { JWT } from "next-auth/jwt"
 
declare module "next-auth/jwt" {
  /** Returned by the `jwt` callback and `auth`, when using JWT sessions */
  interface JWT {
    /** OpenID ID Token */
    idToken?: string
  }
}

モジュール宣言は、プロジェクトのtsconfig.json“含まれる”任意のファイルに追加できます。

リソース

  1. TypeScript ドキュメント:モジュール拡張
  2. DigitalOcean:TypeScript でのモジュール拡張
  3. データベースアダプターの作成