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

How to define type of custom method #36

Closed
JonasHiltl opened this issue Nov 14, 2021 · 2 comments
Closed

How to define type of custom method #36

JonasHiltl opened this issue Nov 14, 2021 · 2 comments

Comments

@JonasHiltl
Copy link

Below is a model im trying to create with a custom method called getPublicUser. It should just be a simple method that returns the public information of a user. But I'm having issues with defining the type of the method because I always get the typescript error:

Type 'UserDoc' does not satisfy the constraint 'Record<string, string | number | boolean | Integer | Point<Integer> | Date<Integer> | Time<Integer> | LocalTime<Integer> | ... 4 more ... | undefined>'.
  Index signature for type 'string' is missing in type 'UserDoc'.

I don't quite understand this error but my guess would be that the constraint for the generic of the ModelFactory does not allow a function to be defined, only Record<string, string | number | boolean | Integer | Point<Integer> | Date<Integer> | Time<Integer> | LocalTime<Integer> | ... 4 more ... | undefined>.

This should either be a bug or I just declared the type of the method at the wrong place.

type IUser = {
    phone?: string;
    phoneVerified?: boolean;
    lastname?: string;
    picture?: string;
    id: string;
    username: string;
    email: string;
    emailVerified: boolean;
    firstname: string;
    password: string;
    role: Role;
}

 UserRelations {}

interface UserDoc extends IUser {
  methods: {
    getPublicUser: () => IPublicUser;
  };
}

export const User = ModelFactory<UserDoc, UserRelations>(
  {
    label: "User",
    primaryKeyField: "id",
    schema: {
      id: {
        type: "string",
        required: true,
        minLength: 1,
        conform: (v) => uuid.validate(v),
      },
      username: {
        type: "string",
        required: true,
      },
      firstname: {
        type: "string",
        required: true,
      },
      lastname: {
        type: "string",
      },
      email: {
        type: "string",
        required: true,
        pattern: EMAIL_REGEX,
      },
      emailVerified: {
        type: "boolean",
        default: false,
        required: true,
      },
      phone: {
        type: "string",
      },
      phoneVerified: {
        type: "boolean",
        default: false,
      },
      picture: {
        type: "string",
      },
      password: {
        type: "string",
      },
      role: {
        type: "string",
        enum: ["USER", "DEV", "ADMIN"],
        required: true,
      },
    },
    methods: {
      getPublicUser: function (): IPublicUser {
        return {
          id: this.id,
          username: this.username,
          firstname: this.firstname,
          lastname: this.lastname,
          email: this.email,
          role: this.role,
          phone: this.phone,
          picture: this.picture,
        };
      },
    },
  },
  neogma
);

User.beforeCreate = async (user) => {
  user.password = await hash(user.password, SALT_ROUNDS);
};
@themetalfleece
Copy link
Owner

themetalfleece commented Nov 14, 2021

Hey Jonas,

Please have a look here (press the "Typescript" tab). You need to something in the lines of:

type IUser = {
    phone?: string;
    phoneVerified?: boolean;
    ...
}

// default value if it's empty
type UserRelations = Object;

interface IUserMethods {
    getPublicUser: (this: UserInstance) => IPublicUser;
}

type IUserStatics = Object;

// import NeogmaInstance
type UserInstance = NeogmaInstance<IUser, UserRelations, IUserMethods>;

export const User = ModelFactory<UserInstance, UserRelations, IUserStatics, IUserMethods>(
    // do not define any methods inside "User"
    ...
}

// the following should have propert typing for for "this" and the return value
User.prototype.getPublicUser = function () {
    // method body here
}

Please me know if you got it working

@JonasHiltl
Copy link
Author

Oh, that makes sense, I never clicked the typescript tab. That's awesome. Thanks a lot for your work creating this library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants