TypeScript无法识别Mongoose子文档_id字段的解决方法问询
Mongoose + TypeScript 子文档_id字段类型推断问题解决
问题场景
在使用Mongoose结合TypeScript开发时,遇到子文档的_id字段无法被TypeScript正确推断的问题。现有两个模型:
User.ts
export const UserSchema = new Schema({ email: { type: String, required: true } }); export default model('User', UserSchema);
Score.ts
export const ScoreSchema = new Schema({ score: { type: Number, required: true }, owner: { type: UserSchema, required: true }, }); export default model('Score', ScoreSchema);
当执行以下代码时,TypeScript会报错提示_id字段不存在,但实际数据库返回的对象中确实包含该字段:
const score = await Score.findById(id); if (score.owner._id.toString() === adminId) { // TypeScript错误:_id字段不存在 console.log("Admin mode"); }
解决方法
1. 显式定义TypeScript接口并结合Mongoose泛型
这是最规范的解决方案,通过定义包含Mongoose默认字段的接口,让TypeScript能正确推断文档结构:
修改User.ts
import { Schema, model, Document } from 'mongoose'; // 定义User文档的类型接口,继承Document以包含_id等默认字段 export interface IUser extends Document { email: string; } // 创建Schema时传入泛型指定接口类型 export const UserSchema = new Schema<IUser>({ email: { type: String, required: true } }); export default model<IUser>('User', UserSchema);
修改Score.ts
import { Schema, model, Document } from 'mongoose'; import { IUser, UserSchema } from './User'; // 定义Score文档的类型接口 export interface IScore extends Document { score: number; owner: IUser; // 直接使用已定义的IUser类型 } export const ScoreSchema = new Schema<IScore>({ score: { type: Number, required: true }, owner: { type: UserSchema, required: true }, }); export default model<IScore>('Score', ScoreSchema);
修改后,TypeScript就能正确识别score.owner._id字段,不会再报错。
2. 临时方案:类型断言(不推荐)
如果不想修改模型定义,可以通过类型断言临时绕过类型检查,但会失去TypeScript的类型校验优势:
const score = await Score.findById(id); if ((score.owner as { _id: { toString: () => string } })._id.toString() === adminId) { console.log("Admin mode"); }
3. 优化TypeScript配置
确保你的tsconfig.json中启用了必要的配置,让Mongoose能更好地生成类型:
{ "compilerOptions": { "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true } }
同时确保安装了@types/mongoose包,保证类型定义的完整性。
内容的提问来源于stack exchange,提问作者csmathhc
相关产品推荐
相关产品推荐

