Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript: Can't extend callback params type #988

Open
kei-ichi opened this issue Jan 20, 2025 · 0 comments
Open

TypeScript: Can't extend callback params type #988

kei-ichi opened this issue Jan 20, 2025 · 0 comments
Labels
bug A bug that needs to be resolved pending An issue waiting for triage

Comments

@kei-ichi
Copy link

Environment


  • Operating System: Darwin
  • Node Version: v22.12.0
  • Nuxt Version: 3.15.2
  • CLI Version: 3.20.0
  • Nitro Version: 2.10.4
  • Package Manager: [email protected]
  • Builder: -
  • User Config: compatibilityDate, ssr, devtools, modules, runtimeConfig, auth
  • Runtime Modules: @sidebase/[email protected]
  • Build Modules: -

Reproduction

You don't need a repo to "reproduce" this issue, just add the @side-base/nuxt-auth model with "auth.js" as it provider then try to extend the callback parameters type using "declare module".

Just in case below is my "minimal" config in the completely new Nuxt 3 project.

nuxt.config.ts file

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  compatibilityDate: '2024-11-01',
  ssr: false,

  devtools: { enabled: true },

  modules: ['@sidebase/nuxt-auth'],

  runtimeConfig: {
    authOrigin: '',
  },

  auth: {
    isEnabled: true,
    originEnvKey: 'NUXT_AUTH_ORIGIN',
    baseURL: '/api/v1/auth',
    provider: {
      type: 'authjs',
      trustHost: true,
      defaultProvider: 'credentials',
      addDefaultCallbackUrl: true,
    },
    globalAppMiddleware: true,
  },
});

NuxtAuthHandler files, you can ignore almost all of it, just focus on the callback code:

import CredentialsProvider from 'next-auth/providers/credentials';
import { NuxtAuthHandler } from '#auth';

interface CustomUser {
  id: string;
  username: string;
  password: string;
}

export default NuxtAuthHandler({
  // A secret string you define, to ensure correct encryption
  secret: 'C4A01200-A1C5-47F5-A392-3F693B973489',
  providers: [
    // @ts-expect-error Use .default here for it to work during SSR.
    CredentialsProvider.default({
      id: 'credentials',
      name: 'Credentials',
      credentials: {
        username: { label: 'Username', type: 'text', placeholder: 'Username' },
        password: {
          label: 'Password',
          type: 'password',
          placeholder: 'Password',
        },
      },
      async authorize(credentials: { username: string; password: string }) {
        // Add logic here to look up the user from the credentials supplied

        console.log(`=======================================`);
        console.log(`Authorized credentials:`);
        console.log(JSON.stringify(credentials));
        console.log(`=======================================`);

        const user = {
          id: crypto.randomUUID(),
          username: credentials.username,
          // password: credentials.password,
        };

        console.log(`Credentials: ${JSON.stringify(user)}`);

        if (credentials.username && credentials.password) {
          // Any object returned will be saved in `user` property of the JWT
          return user;
        } else {
          // If you return null then an error will be displayed advising the user to check their details.
          return null;

          // You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter
        }
      },
    }),
  ],
  // Callbacks should be here at the root level
  callbacks: {
    async signIn({ user, account, profile, email, credentials }) {
      console.log(`------------------ BEFORE SIGN IN -------------------`);
      console.log(user);
      console.log(`------------------ BEFORE SIGN IN -------------------`);
      return true;
    },
    async jwt({ token, user, account, profile, isNewUser }) {
      console.log(`------------------JWT-------------------`);
      console.log('JWT Callback - Input token:', token);
      console.log('JWT Callback - Input user:', user);
      console.log(`------------------JWT-------------------`);

      if (user) {
        return {
          ...token,
          userData: {
            // Store user data in a dedicated property
            id: user.id,
            username: user.username,
          },
        };
      }

      return token;
    },
    async session({ session, user, token }) {
      console.log('Session Callback - Input session:', session);
      console.log('Session Callback - Input token:', token);

      // Make sure user data is copied to session
      if (token.userData) {
        session.user = token.userData;
      }

      console.log('Session Callback - Returning session:', session);
      return session;
    },
    async redirect({ url, baseUrl }) {
      console.log(`------------------ REDIRECT URL -------------------`);
      console.log(url);
      console.log(baseUrl);
      console.log(`---------------------------------------------------`);
      return url;
    },
  },
});

This part for more specific

      if (user) {
        return {
          ...token,
          userData: {
            // Store user data in a dedicated property
            id: user.id,
            username: user.username, <---------------- THIS IS WHERE THE ISSUE HAPPEN
          },
        };
      }

The user.username got the below error:

Vue: Property username does not exist on type User | AdapterUser
Property username does not exist on type User

But I did extend that User interface/types like this:

import '#auth';

declare module '#auth' {
  interface User {
    id: string;
    username: string;
    password?: string;
  }
}

And if I click to the User type when hover my mouse to the user I got property type as below:

export interface module:.auth. User {    
       id: string     
       username: string 
}
 
shared/types/nuxt-auth.ts

Image

Image

Image

Image

Describe the bug

TypeScript: Cannot extend User type despite it being declared and visible in IDE and the official docs don't have any "section" on when using with TypeScript but the original package Auth.js have

I did describe this issue detailed in the Reproduction sections so I will not repeat it here.

I will be very appreciated, If anyone have same issue or have a solutions to this issue, please add a comment.

To this package dev teams, please add a document about TypeScript usage.

Additional context

No response

Logs

@kei-ichi kei-ichi added bug A bug that needs to be resolved pending An issue waiting for triage labels Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug that needs to be resolved pending An issue waiting for triage
Projects
None yet
Development

No branches or pull requests

1 participant