如何在TypeScript环境下为Mongoose模型关联类型实现静态检查
解决方法
1. 移除冲突依赖
确认使用Mongoose 6.0及以上版本,卸载已废弃的@types/mongoose包,避免内置类型和第三方类型冲突:
npm uninstall @types/mongoose
2. 修正模型定义文件的类型声明
需要给mongoose.model显式传入文档类型泛型,同时修正接口字段类型和Schema中定义的存储类型匹配:
import mongoose, { HydratedDocument } from "mongoose"; const { Schema } = mongoose; // 定义和数据库存储结构匹配的接口 interface Album { title: string; // 对应Schema的Decimal128类型,不要使用Number price: mongoose.Types.Decimal128; } const schema = new Schema<Album>({ title: { type: String, required: true }, price: Schema.Types.Decimal128 }); // 给model传入泛型,指定该模型对应的文档类型 // HydratedDocument会自动包含Mongoose文档的内置属性和方法 const albums = mongoose.model<HydratedDocument<Album>>("albums", schema); export default albums;
3. 修正路由文件代码
首先修正变量重名问题,之后就可以直接通过.运算符访问文档属性,TS会自动推导类型:
import express from "express"; import albums from "../../models/albums"; const router = express.Router(); router.get("/api/albums", async (req, res) => { // 此时_albums会被自动推导为 HydratedDocument<Album>[] 类型 const _albums = await albums.find({}); // item会被推导为 HydratedDocument<Album> 类型,支持直接点取属性 const formattedAlbums = _albums.map((item) => { return { // 注意方法名是小写开头的toUpperCase,TS会自动检查拼写错误 title: item.title.toUpperCase() } }); // 后续业务逻辑,比如返回响应 res.json(formattedAlbums); }); export default router;
验证效果
修改完成后,将鼠标悬停在_albums和item变量上,就能看到对应的类型声明,访问不存在的属性、拼写错误都会触发TS的静态检查提示。
内容的提问来源于stack exchange,提问作者Kgn-web
相关产品推荐
相关产品推荐

