Home > OS >  Use exported modules as a union type
Use exported modules as a union type

Time:10-28

I am trying to figure out a way to use exported modules' list as a type. Let's say I have three files:

// schemas/auth.ts
import Joi, { Schema } from 'joi';

export const login: Schema = Joi.object({
  username: Joi.string().alphanum().min(3).max(30).required(),
  password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),
});
// schemas/index.ts
import { login } from './auth';

export default { login };

And, for the validation middleware:

import { NextFunction, Request, Response } from 'express';

import schemas from '../schemas';

export default (schema: string) => {
  if (!schemas.hasOwnProperty(schema))
    throw new Error(`'${schema}' validator is not exist`);

  return async function (req: Request, _res: Response, next: NextFunction) {
    try {
      const validated = await schemas[schema].validateAsync(req.body);
      req.body = validated;
      next();
    } catch (err) {
      if (err.isJoi) console.log(err);

      // return next(createHttpError(422, { message: err.message }));
      next();
    }
  };
};

This validator will not work as is because TypeScript cannot be sure if passed in schema string has a corresponding module in schemas, so I have to somehow say "Parameter schema can only be one of the exported modules' name". What would be the best way to achieve this?

CodePudding user response:

You can use type keyof typeof schemas to have validation function only accept strings that exist as key of schemas.

TS Documentation: https://www.typescriptlang.org/docs/handbook/2/keyof-types.html

  • Related