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

如何在TypeScript中定义NestJS Mongoose嵌套对象Schema:仅单个字段必填,其余为不限数量的字符串类型键?

在TypeScript + Mongoose中实现带必填字段的嵌套动态键结构

你的问题核心是要定义一个嵌套的Mongoose子文档,其中en字段必填,同时允许任意数量的额外字符串类型键。之前的代码报错主要有两个原因:

  1. 嵌套子文档不需要继承mongoose.Document(这个类是给顶级集合文档用的);
  2. Mongoose默认的strict模式会拒绝Schema中未定义的字段,且装饰器无法直接处理显式属性+索引签名的组合。

下面是正确的实现方式:

步骤1:定义TypeScript类型与Mongoose Schema类

import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';
import * as mongoose from 'mongoose';

// 先定义TypeScript类型,确保编译时的类型安全
type TranslationsType = {
  en: string;
} & Record<string, string>;

// 嵌套子文档无需继承mongoose.Document
@Schema({ _id: false, strict: false }) // strict: false允许额外字段存入数据库
class Translations {
  @Prop({ required: true, type: String })
  en: string;

  // 索引签名确保所有额外键的类型都是字符串
  [key: string]: string;
}

export const TranslationsSchema = SchemaFactory.createForClass(Translations);

步骤2:添加额外字段类型验证(可选但推荐)

虽然TypeScript的类型检查能在编译时约束额外键的类型,但为了防止数据库存入不符合要求的数据,可以给Schema添加前置验证逻辑:

// 在Schema创建后添加验证钩子
TranslationsSchema.pre('validate', function(next) {
  const doc = this as TranslationsType;
  for (const key in doc) {
    // 检查除en外的所有字段是否为字符串类型
    if (key !== 'en' && typeof doc[key] !== 'string') {
      return next(new Error(`字段 ${key} 必须是字符串类型`));
    }
  }
  next();
});

如何在父文档中使用这个嵌套Schema

比如你有一个Product文档需要包含多语言翻译字段:

@Schema()
class Product {
  @Prop({ type: TranslationsSchema, required: true })
  translations: TranslationsType;

  // 其他业务字段...
}

export const ProductSchema = SchemaFactory.createForClass(Product);

配置完成后,你就可以创建符合要求的文档实例:

const product = new Product({
  translations: {
    en: "Fresh Apple",
    zh: "新鲜苹果",
    ja: "新鮮なリンゴ"
  }
});

关键细节说明

  • strict: false:Mongoose默认会忽略Schema中未定义的字段,开启这个选项后允许额外字段被正常存入数据库;
  • 索引签名[key: string]: string:确保TypeScript编译时检查所有额外键的类型合法性;
  • 不继承mongoose.Document:嵌套子文档不需要这个基类,只有顶级集合的文档才需要继承它。

内容的提问来源于stack exchange,提问作者Dima Binskyi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:47:45