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