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 errors when creating a custom User model #861

Closed
betfix opened this issue Nov 18, 2020 · 8 comments
Closed

Typescript errors when creating a custom User model #861

betfix opened this issue Nov 18, 2020 · 8 comments
Labels
question Ask how to do something or how something works TypeScript Issues relating to TypeScript

Comments

@betfix
Copy link

betfix commented Nov 18, 2020

How to make a custom User model in Typescript and add it to NextAuth options?

I am trying to make a custom user model (following the tutorial https://next-auth.js.org/tutorials/typeorm-custom-models), but the app won't build because of typescript errors. It runs with "yarn dev" command and works ok with this model, but it throws errors with "yarn build" command.

The first error is in the custom model User.ts which I created, in the class definition:

export default class User extends Adapters.TypeORM.Models.User.model {
...
}

The string "Adapters.TypeORM.Models.User.model" is underlined in red and the error says: "Type 'TypeORMUserModel' is not a constructor function type"

The second typescript error is in pages/api/auth/[...nextauth].ts in options:

import Models from '../../../backend/models'
const options = {
  ......
  adapter: Adapters.TypeORM.Adapter(
    {
      type: 'postgres',
      ......
    },
    {
      models: {
        User: Models.User,
      },
    }
  ),
}

The string "User:" is underlined in red and the error says:

"Type '{ model: typeof User; schema: { name: string; target: typeof User; columns: { phoneNumber: { type: string; nullable: boolean; }; name?: EntitySchemaColumnOptions; email?: EntitySchemaColumnOptions; image?: EntitySchemaColumnOptions; emailVerified?: EntitySchemaColumnOptions; }; }; }' is not assignable to type '{ model: any; schema: EntitySchemaOptions<any>; }'.
  The types of 'schema.columns' are incompatible between these types.
    Type '{ phoneNumber: { type: string; nullable: boolean; }; name?: EntitySchemaColumnOptions; email?: EntitySchemaColumnOptions; image?: EntitySchemaColumnOptions; emailVerified?: EntitySchemaColumnOptions; }' is not assignable to type '{ [x: string]: EntitySchemaColumnOptions; }'.
      Property 'phoneNumber' is incompatible with index signature.
        Type '{ type: string; nullable: boolean; }' is not assignable to type 'EntitySchemaColumnOptions'.
          Types of property 'type' are incompatible.
            Type 'string' is not assignable to type 'ColumnType'.ts(2322)
adapters.d.ts(77, 17): The expected type comes from property 'User' which is declared here on type '{ Account?: { model: any; schema: EntitySchemaOptions<any>; }; User?: { model: any; schema: EntitySchemaOptions<any>; }; Session?: { model: any; schema: EntitySchemaOptions<...>; }; VerificationRequest?: { ...; }; }'"

My custom User model (copied from the tutorial):

import Adapters from "next-auth/adapters"
export default class User extends Adapters.TypeORM.Models.User.model {
   constructor(name, email, image, emailVerified) {
    super(name, email, image, emailVerified)
  }
}
export const UserSchema = {
  name: "User",
  target: User,
  columns: {
    ...Adapters.TypeORM.Models.User.schema.columns,
    phoneNumber: {
      type: "varchar",
      nullable: true,
    },
  },
}
@betfix betfix added the question Ask how to do something or how something works label Nov 18, 2020
@paul-vd
Copy link
Contributor

paul-vd commented Nov 24, 2020

I'm getting exactly the same errors on a new project. As a temp fix, I updated the import method:

import Adapters, {TypeORMUserModel} from 'next-auth/adapters'

export default class User extends TypeORMUserModel {
  ...
}

@xangxiong
Copy link

xangxiong commented Nov 24, 2020

Using TypeORMUserModel seems to throw undefined. What seems to work for me was:

import Adapters from 'next-auth/adapters';

export default class User extends (<any>Adapters.TypeORM.Models.User.model) {
    constructor(name, email, image, emailVerified) {
        super(name, email, image, emailVerified);
    }
}

@sebastianplsim
Copy link

So - it's not pretty, but this works for me. FYI I'm adding a username - not telephone.

Let me know if you know a way to tidy this up a little.

User.ts

import Adapters from 'next-auth/adapters'
import { EntitySchemaColumnOptions } from 'typeorm'

export default class User extends (<any>Adapters.TypeORM.Models.User.model) {
  constructor(name, email, image, emailVerified) {
    super(name, email, image, emailVerified)
  }
}

type UserSchema = {
  name: string
  target: typeof User
  columns: {
    username?: {
      type: 'varchar'
      nullable: boolean
    }
    name?: EntitySchemaColumnOptions
    email?: EntitySchemaColumnOptions
    image?: EntitySchemaColumnOptions
    emailVerified?: EntitySchemaColumnOptions
  }
}

export const UserSchema: UserSchema = {
  name: 'User',
  target: User,
  columns: {
    ...Adapters.TypeORM.Models.User.schema.columns,
    username: {
      type: 'varchar',
      nullable: true,
    },
  },
}

@balazsorban44 balazsorban44 added the TypeScript Issues relating to TypeScript label Jan 18, 2021
@jaretburkett
Copy link

This appears to work for me and allows for proper type completions.

import Adapters, {TypeORMUserModel} from 'next-auth/adapters';

export default class User extends (Adapters.TypeORM.Models.User.model as typeof TypeORMUserModel)  {

@serdarsavas
Copy link

This appears to work for me and allows for proper type completions.

import Adapters, {TypeORMUserModel} from 'next-auth/adapters';

export default class User extends (Adapters.TypeORM.Models.User.model as typeof TypeORMUserModel)  {

Screenshot 2021-05-26 at 11 25 20

Asks me to convert type to unknown

@PiotrFidurski
Copy link

PiotrFidurski commented Jun 8, 2021

I got it working with the following code, I specified each model needed for Adapter: Account Session VerificationRequest:

[...nextauth].ts

adapter: Adapters.TypeORM.Adapter(process.env.MONGODB_URI!, {
  models: {
    // I suppose you could also spread models here ...Adapters.TypeORM.Models
    Account: Adapters.TypeORM.Models.Account,
    Session: Adapters.TypeORM.Models.Session,
    VerificationRequest: Adapters.TypeORM.Models.VerificationRequest,
    User: Models.User,
   },
})

Models/User.ts

export default class User extends (<any>Adapters.TypeORM.Models.User.model) {
  constructor(
    name: string,
    email: string,
    image: string,
    emailVerified: Date | undefined
  ) {
    super(name, email, image, emailVerified);
    if (!this.username) this.username = this.name;
    if (!this.isFollowed) this.isFollowed = false;
  }
}

type UserSchema = {
  name: string;
  target: typeof TypeORMUserModel;
  columns: {
    username?: {
      type: "varchar";
      nullable: boolean;
    };
    isFollowed?: {
      type: "boolean";
    };
    name?: EntitySchemaColumnOptions;
    email?: EntitySchemaColumnOptions;
    image?: EntitySchemaColumnOptions;
    emailVerified?: EntitySchemaColumnOptions;
  };
};

export const UserSchema: UserSchema = {
  name: "User",
  target: User,
  columns: {
    ...Adapters.TypeORM.Models.User.schema.columns,
    username: {
      type: "varchar",
      nullable: true,
    },
    isFollowed: {
      type: "boolean",
    },
  },
};

@hademo
Copy link

hademo commented Aug 22, 2021

I'm getting exactly the same errors on a new project. As a temp fix, I updated the import method:

import Adapters, {TypeORMUserModel} from 'next-auth/adapters'

export default class User extends TypeORMUserModel {
  ...
}

Gives me following error "TypeError: Class extends value undefined is not a constructor or null" at local dev

@hademo
Copy link

hademo commented Aug 22, 2021

Using TypeORMUserModel seems to throw undefined. What seems to work for me was:

import Adapters from 'next-auth/adapters';

export default class User extends (<any>Adapters.TypeORM.Models.User.model) {
    constructor(name, email, image, emailVerified) {
        super(name, email, image, emailVerified);
    }
}

Not really pretty, but works perfect

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Ask how to do something or how something works TypeScript Issues relating to TypeScript
Projects
None yet
Development

No branches or pull requests

9 participants