如何将导出模块名称设为联合类型限制TypeScript验证中间件入参
最优实现方案
你只需要通过类型推导提取schemas对象的键作为入参类型即可,无需手动维护枚举或者联合类型,后续新增schema时会自动同步扩展可选值,具体修改如下:
1. 调整schemas导出配置(可选但推荐)
在schemas/index.ts中给导出的对象加上as const,锁死对象的类型结构,避免TS将键类型拓宽为通用string类型,还可以直接导出键类型方便其他模块复用:
// schemas/index.ts import { login } from './auth'; const schemas = { login } as const; export default schemas; export type SchemaName = keyof typeof schemas;
2. 修改验证中间件的入参类型
将中间件入参的string类型替换为刚才导出的SchemaName类型即可,如果没有提前导出该类型也可以直接写keyof typeof schemas:
import { NextFunction, Request, Response } from 'express'; import schemas, { SchemaName } from '../schemas'; export default (schema: SchemaName) => { // 原有运行时检查保留,用于兜底绕过TS类型检查的异常调用 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(); } }; };
实现效果
- 调用中间件时传入非现有schema名称的字符串,TS会直接抛出类型错误
- IDE会自动提示现有可用的schema名称,提升开发效率
- 后续新增schema只需在schemas模块中正常导出即可,可选值类型会自动更新,无需额外手动维护
内容的提问来源于stack exchange,提问作者Özenç B.
相关产品推荐
相关产品推荐

