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
の拡張を見てみましょう。
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
はすべて拡張できます。ユースケースに基づいてオーバーライドしたい一般的なインターフェースをいくつか紹介します。
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
に“含まれる”任意のファイルに追加できます。