You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 06:55:03