TypeScript结合Mongoose时的两类类型校验问题咨询
TypeScript + Mongoose 开发问题解答
问题描述
我在使用TypeScript与Mongoose开发时遇到两个问题:
- 定义的Coin类型中symbol和name字段为何会变为可选(partial)类型?
- Mongoose为何无法检测到Schema中定义的、不存在于IDocument接口的无效键
noItem?
相关代码(model.ts)
type Coin = { symbol: string; name: string; } interface IDocument extends Coin {} const Schema: mongoose.Schema<IDocument> = new mongoose.Schema({ symbol: String, noItem: Number, });
问题解答
1. symbol和name变为可选类型的原因
Mongoose的Schema<T>泛型默认会将传入的类型转换为可选类型,这是因为Mongoose文档天生支持部分字段更新、增量创建等场景。另外,你的IDocument仅继承了自定义的Coin类型,没有和Mongoose核心的Document类型结合,导致TypeScript无法正确识别字段的必填性约束。
解决方法是让IDocument继承mongoose.Document,同时在Schema中明确标记字段为必填:
import mongoose from 'mongoose'; type Coin = { symbol: string; name: string; } interface IDocument extends Coin, mongoose.Document {} const Schema = new mongoose.Schema<IDocument>({ symbol: { type: String, required: true }, name: { type: String, required: true }, });
这样TypeScript会强制symbol和name为必填项,Mongoose也会在数据库层面做校验。
2. Schema中无效键未被检测的原因
Mongoose默认允许Schema包含泛型类型中未定义的字段,TypeScript的类型检查不会主动拦截这种不匹配。要实现严格校验,需要同时开启Mongoose的严格模式和TypeScript的严格类型检查。
修改步骤:
- 在Schema配置中设置
strict: true(Mongoose 6+默认开启,旧版本需手动添加) - 确保TypeScript配置文件中的
strict选项设为true,增强类型校验
修改后的代码:
const Schema = new mongoose.Schema<IDocument>({ symbol: { type: String, required: true }, noItem: Number, // 此时TypeScript会抛出错误:noItem不在IDocument类型中 }, { strict: true });
开启严格模式后,Mongoose会拒绝保存Schema未定义的字段,同时TypeScript会检测到无效键并报错。
内容的提问来源于stack exchange,提问作者new of man
相关产品推荐
相关产品推荐

