Replacing a Mongo Document Type with the correct type

Viewed 15

I have this object:

export class User {
  email: string;
  hashedPassword: string;
  dateCreated: Date;
  plan: string;
  directAffiliateSignup: boolean;
  referralPromoCode: string;
  referredBy: Referrer;

  constructor({
    email,
    hashedPassword,
    plan,
    directAffiliateSignup,
  }: UserConstructor) {
    this.email = email.toLowerCase();
    this.hashedPassword = hashedPassword;
    this.dateCreated = new Date();
    this.plan = plan;
    this.directAffiliateSignup = directAffiliateSignup;
    this.referralPromoCode = uuidv4();
    this.referredBy = null;
  }

  signToken(expiry: number | string = 60 * 24): string {
    const secret = process.env.JWT_SECRET as Secret;
    // { ...this } overcomes error `Expected "payload" to be a plain object`
    const token = jwt.sign({ ...this }, secret, {
      expiresIn: expiry,
    });
    return token;
  }

  async saveToDb(): Promise<InsertOneResult<Document>> {
    const collection = getCollection(USERS_COLLECTION_NAME);
    const saveResult = await collection.insertOne(this);
    if (!saveResult) {
      throw new HttpError(500, 'Could not insert user into the database');
    }
    return saveResult;
  }

  async addReferrer(referralPromoCode: string): Promise<undefined> {
    const validReferrer = await User.findReferrer(referralPromoCode);
    if (!validReferrer) return;
    this.referredBy = referralPromoCode;
  }

  static async delete(id: string): Promise<DeleteResult> {
    const collection = getCollection(USERS_COLLECTION_NAME);
    const user = await User.findById(id);
    if (!user) throw new HttpError(404, 'User not found');
    const deleteResult = await collection.deleteOne(user);
    if (!deleteResult) throw new HttpError(500, 'Could not delete user');
    return deleteResult;
  }

  static async fetchAll(limit: number, skip: number = 0): Promise<any> {
    const collection = getCollection(USERS_COLLECTION_NAME);
    const users = await collection.find().limit(limit).skip(skip).toArray();
    if (!users) throw new HttpError(404, 'Could not find any users');
    return users;
  }
}

And I want to improve the type of this part (for example):

async saveToDb(): Promise<InsertOneResult<Document>> {

Having Document seems a little vague to me, so I thought the type should instead be this:

Promise<InsertOneResult<User>>

But I don’t know whether the above is right or wrong. The above does not seem to show any linting errors, but I can also do this and it shows no linting errors:

class Dog {
  name: string;
}

async saveToDb(): Promise<InsertOneResult<Dog>> {

And I know that the above should definitely be incorrect as the insert does not insert a Dog object.

Does anyone know how to improve this? Just using Document seems against the principle of why we should use typescript in the first place.

0 Answers
Related