'Express Mongoose API Factory

I'm trying to create API factory for node.js, Express, Mongoose Tech stack. I also want to provide full type safety using Typescript and the option to add additional validation for creation and updates. For example I have "validator" like that:

type ICheckIfUnique = <M, T extends Model<M>, K extends keyof M>(
  attributes: {
    model: T;
    key: K;
  },
  body: M
) => void;

export const checkIfUnique: ICheckIfUnique = async (attributes, body) => {
  const { model, key } = attributes;
  const value = body[key];
  const isUnique = !(await model.findOne({ [key]: value }));
  if (!isUnique) {
    throw `${key} is not unique!`;
  }
};

But I can't get the type right as I get:

enter image description here

I can't also find way to get custom model types for the factory methods:

export const factoryCreateEndpoint =
  <T, D extends Model<T>>(model: D, additionalLogic?: any) =>
  async (req: Request, res: Response): Promise<Response | undefined> => {
    const body = req.body;

    if (!body) {
      return res.status(400).json({
        success: false,
        error: `You must provide ${capitalize(
          model.collection.name.slice(0, -1)
        )}.`,
      });
    }

    if (additionalLogic) {
      try {
        for (const element in additionalLogic) {
          const { validator, additionalVariables } = additionalLogic[element];
          await validator(additionalVariables, req.body);
        }
      } catch (error) {
        return res.status(400).json({ success: false, error });
      }
    }

    try {
      const object = new model(body);
      await object.save();
      return res.status(201).json({
        success: true,
        id: object._id,
        message: `${capitalize(model.collection.name.slice(0, -1))} created.`,
      });
    } catch (error) {
      return res.status(400).json({ success: false, error });
    }
  };

But with this generic type I get:

enter image description here



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source