Issue
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?
Solution
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
Answered By – Joonas
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0