nuxt-community / auth-module

Zero-boilerplate authentication support for Nuxt 2
https://auth.nuxtjs.org
MIT License
1.93k stars 926 forks source link

Define this.$auth.user type #1097

Open Pacheco95 opened 3 years ago

Pacheco95 commented 3 years ago

I'm using typescript and I need to change this.$auth.user to correct type. It's default typed as Record<string, unknown> | null from @nuxtjs/auth-next/dist/index.d.ts. How can I overwrite this type definition?

I tried to create an index.d.ts file in my src/types directory with the following content, but it doesn't work

// Still reading default type
import { Auth } from '@nuxtjs/auth-next/dist'
import { Collaborator } from '~/interfaces/Collaborator'

declare module '@nuxtjs/auth-next' {
  interface Vue {
    $auth: Auth & { user: Collaborator }
  }
}
declare module 'vue/types/vue' {
  interface Vue {
    $auth: Auth & { user: Collaborator }
  }
}

The latter approach gives me this error message:

TS2717: Subsequent property declarations must have the same type.
Property '$auth' must be of type 'Auth', but here has type 'Auth & { user: Collaborator; }'.
productdevbook commented 3 years ago

hi, Did you find a solution for this?

Pacheco95 commented 3 years ago

Unfortunately no :/

dioncodes commented 3 years ago

I'm currently using const user = this.$auth.user as User but obviously that's not a real solution... Would be great to be able to define the type of $auth.user. I tried something similar to the code above but couldn't get it to work either.

Pacheco95 commented 3 years ago

Yes, @dioncodes, i'm currently using this approach until someone help us. But it's very anoying doing this every time

acidjazz commented 3 years ago

+1 for this feature, not sure how how we would specify our own types, until then here is another workaround I use:

import { User } from '@/types/api'
import { Auth } from '@nuxtjs/auth-next'

export interface PublisherConstructorParams {
  auth: Auth & { user: User }
maou-shonen commented 3 years ago

I'm a beginner in typescript, I'm not sure if it's wrong, but it's working well in my project

// index.d.ts
import { Auth as NuxtAuth } from '@nuxtjs/auth-next'

export interface User {
  id: string
  name: string
}

declare module 'vue/types/vue' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module '@nuxt/types' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module 'vuex/types/index' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}
brokenfiles commented 3 years ago

I'm a beginner in typescript, I'm not sure if it's wrong, but it's working well in my project

// index.d.ts
import { Auth as NuxtAuth } from '@nuxtjs/auth-next'

export interface User {
  id: string
  name: string
}

declare module 'vue/types/vue' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module '@nuxt/types' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module 'vuex/types/index' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

Does it work as the "user" object has the type "User" in the context of "this.$auth"? Can I see your tsconfig.js and where is your "index.d.ts" file stored ?

IlyaSemenov commented 3 years ago

I'm using a patch for patch-package:

diff --git a/node_modules/@nuxtjs/auth-next/dist/index.d.ts b/node_modules/@nuxtjs/auth-next/dist/index.d.ts
index 4a0651e..3cbad48 100644
--- a/node_modules/@nuxtjs/auth-next/dist/index.d.ts
+++ b/node_modules/@nuxtjs/auth-next/dist/index.d.ts
@@ -4,6 +4,8 @@ import type { Context } from '@nuxt/types';
 import type { Middleware } from '@nuxt/types';
 import type { NuxtAxiosInstance } from '@nuxtjs/axios';

+export interface User {}
+
 export declare class Auth {
     ctx: Context;
     options: ModuleOptions;
@@ -19,7 +21,7 @@ export declare class Auth {
     get state(): any;
     get strategy(): Scheme;
     getStrategy(throwException?: boolean): Scheme;
-    get user(): Record<string, unknown> | null;
+    get user(): User | null;
     get loggedIn(): boolean;
     get busy(): boolean;
     init(): Promise<void>;

and then this in my code:

declare module '@nuxtjs/auth-next' {
  interface User {
    id: string
    name: string
  }
}
maou-shonen commented 3 years ago

I'm a beginner in typescript, I'm not sure if it's wrong, but it's working well in my project

// index.d.ts
import { Auth as NuxtAuth } from '@nuxtjs/auth-next'

export interface User {
  id: string
  name: string
}

declare module 'vue/types/vue' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module '@nuxt/types' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module 'vuex/types/index' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

Does it work as the "user" object has the type "User" in the context of "this.$auth"? Can I see your tsconfig.js and where is your "index.d.ts" file stored ?

Yes, this working in this.$auth context and in vuex store


My index.d.ts is at root
The User interface is located in the types folder, import in index.d.ts


My tsconfig.json

{
  "compilerOptions": {
    "target": "ES2018",
    "module": "ESNext",
    "moduleResolution": "Node",
    "lib": ["ESNext", "ESNext.AsyncIterable", "DOM"],
    "esModuleInterop": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "~/*": ["./*"],
      "@/*": ["./*"]
    },
    "types": [
      "node",
      "@types/node",
      "@nuxt/types",
      "@nuxtjs/axios",
      "@nuxtjs/auth-next",
      "@nuxtjs/device",
      "@nuxtjs/dayjs",
      "nuxt-i18n",
      "vuetify",
      "animejs"
    ],
    "typeRoots": ["./node_modules/@types", "./node_modules/vuetify/types"]
  },
  "exclude": ["node_modules", ".nuxt", "dist"]
}

this.$auth like

Snipaste_2021-06-23_08-27-59

brokenfiles commented 3 years ago

I fixed my problem, thank you a lot for your answer!

Myzel394 commented 3 years ago

The solution above didn't work for me. Here's what worked for me:

import { Auth as NuxtAuth } from "@nuxtjs/auth-next"
import User from "~/types/user"

declare module "vue/types/vue" {
    interface Vue {
        // @ts-ignore
        $auth: NuxtAuth & {
            user: User
        }
    }
}
acidjazz commented 3 years ago

@Myzel394 nice!

oscarhandsome commented 2 years ago

The above solution helps only for a new version of @nuxt/auth For version 4 can help solution here

szulcus commented 2 years ago

I'm a beginner in typescript, I'm not sure if it's wrong, but it's working well in my project

// index.d.ts
import { Auth as NuxtAuth } from '@nuxtjs/auth-next'

export interface User {
  id: string
  name: string
}

declare module 'vue/types/vue' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module '@nuxt/types' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

declare module 'vuex/types/index' {
  interface Auth extends NuxtAuth {
    user: User & typeof NuxtAuth.prototype.user
  }
}

I have a problem with this solution, but it turns out that without & typeof NuxtAuth.prototype.user everything works fine. Thanks! image

steklopod commented 2 years ago

Here is related topic for alternative auth module for nuxt 3: https://github.com/Teranode/nuxt-module-alternatives/issues/82

Still looking for best practice...