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

Mongoose返回文档的TypeScript函数返回类型错误如何解决?

Mongoose + TypeScript 查询函数返回类型定义错误解决

问题场景

项目中使用Mongoose编写查询函数返回模型文档,迁移到TypeScript时,定义返回类型遇到以下问题:

Box模型代码

import mongoose, { Schema, Types } from 'mongoose';

export interface Box {
  name: string
  set: Types.ObjectId
}

const BoxSchema = new Schema({
    name: { type: String, unique: true, required: true, dropDups: true },
    set: { type: Schema.Types.ObjectId, ref: 'Set', required: true }
});

const Box = mongoose.model<Box>('Box', BoxSchema);
export default Box;

原始控制器代码

import Box from '../models/Box';

static async getAllBoxes () {
  return await Box.find({}).exec();
}

尝试按照IDE提示定义返回类型后,抛出错误:

'Box' refers to a value, but is being used as a type here. Did you mean 'typeof Box'?

改为typeof Box后,又出现类型不匹配错误:

Type '(Document<unknown, any, Box> & Box & { _id: ObjectId; })[]' is not assignable to type '(Document<unknown, any, Model<Box, {}, {}, {}, any>> & Model<Box, {}, {}, {}, any> & { id: ObjectId; })[]'.

解决方案

方法1:自定义文档类型(通用兼容方案)

在Box模型文件中,明确导出Mongoose文档实例类型(即数据库返回的 hydrated 文档类型,包含_id、save()等Mongoose内置属性和方法):

import mongoose, { Schema, Types, Document } from 'mongoose';

export interface Box {
  name: string
  set: Types.ObjectId
}

// 定义文档类型:合并自定义接口与Mongoose Document属性
export type BoxDocument = Document<unknown, any, Box> & Box & {
  _id: Types.ObjectId;
};

const BoxSchema = new Schema({
    name: { type: String, unique: true, required: true, dropDups: true },
    set: { type: Schema.Types.ObjectId, ref: 'Set', required: true }
});

// 创建模型时使用自定义文档类型
const Box = mongoose.model<BoxDocument>('Box', BoxSchema);
export default Box;

然后在控制器中直接使用该类型:

import Box, { BoxDocument } from '../models/Box';

static async getAllBoxes(): Promise<BoxDocument[]> {
  return await Box.find({}).exec();
}

方法2:使用Mongoose官方HydratedDocument类型(Mongoose 6.0+)

Mongoose 6.0及以上版本提供了HydratedDocument类型,可直接生成文档实例类型,无需手动定义:

在控制器中导入并使用:

import Box, { Box } from '../models/Box';
import { HydratedDocument } from 'mongoose';

static async getAllBoxes(): Promise<HydratedDocument<Box>[]> {
  return await Box.find({}).exec();
}

错误原因说明

  • 直接使用Box作为类型时,Box是默认导出的模型实例(值),而非TypeScript类型,因此报错。
  • 使用typeof Box得到的是模型类的类型,不是数据库返回的文档实例类型,导致类型不匹配。
  • 正确的做法是使用Mongoose提供的文档实例类型(自定义BoxDocument或官方HydratedDocument),这类类型会合并自定义接口与Mongoose内置的文档属性,与查询返回值的类型完全匹配。

内容的提问来源于stack exchange,提问作者Daniel Corona

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:45:41