访问数组中嵌入鉴别器的属性会引发错误

问题描述 投票:0回答:1

在我的 NestJS 应用程序中,在我的 Mongoose 模式之一中,我在数组中嵌入了鉴别器。当迭代数组并尝试访问特定于一个鉴别器的字段时,由于某种原因该字段未定义。

这里可以参考 NestJS 文档,了解如何处理鉴别器。

架构定义

用户

@Schema()
export class User {
  @Prop({ required: true, type: [BaseAction] })
  subscriptionHistory: BaseAction[];
}

export const UserSchema = SchemaFactory.createForClass(User);
export type UserModel = Model<User>;
export type UserDocument = HydratedDocument<User>;

BaseAction 和判别器

@Schema({ _id: false, discriminatorKey: 'action', autoCreate: false })
export class BaseAction {
  @Prop({ required: true, type: String, enum: SubscriptionAction })
  action: string;

  @Prop({ default: Date.now })
  timestamp: Date;
}
export const BaseActionSchema = SchemaFactory.createForClass(BaseAction);


@Schema({ _id: false })
export class UpgradeAction {
  action: string = SubscriptionAction.Upgrade;
  timestamp: Date;

  @Prop({ required: true, type: Object })
  details: SubscriptionChange & StartDateChange & EndDateChange;
}
export const UpgradeActionSchema = SchemaFactory.createForClass(UpgradeAction);

/*
 * Here exemplary the SubscriptionChange helper used in the 'details' prop
 */
@Schema({ _id: false })
class SubscriptionChange {
  @Prop({ required: true })
  oldVersion: number;

  /* Some more properties */
}

模块

@Module({
  imports: [
    MongooseModule.forFeature([
      { name: User.name, schema: UserSchema },
      {
        name: BaseAction.name,
        schema: UserSchema.path('subscriptionHistory').schema,
        discriminators: [
          { name: SubscriptionAction.Upgrade, schema: UpgradeActionSchema },
          /* further discriminators here */
        ],
      },
    ])
  ],
  /* controllers, providers, exports */
})
export class UserModule {}

问题

在我的一项服务中,我从数据库中检索用户并迭代 subscriptionHistory 数组。我检查操作类型,然后想要读取操作的

details
属性。

在调试中运行时,我可以看到详细信息字段在内存中,但每当我访问它时,它都是未定义的。

export class SomeService {
  async someHandler(userId) {
    const user = await this.userService.getUserById(userId); // works fine

    const action = user.subscriptionHistory.find((h) => {
      if (h.action === SubscriptionAction.Upgrade) { // works fine
        console.log(h) // <-- 'details' is being printed
        const { details } = h as UpgradeAction // I have to cast to be able to extract details
        return details.oldVersion > 1; // This throws
      }
    });
  }
}

抛出的错误是:

无法读取未定义的属性(读取“oldVersion”)

在调试器中,我可以看到

h
的类型为
EmbeddedDocument
并且
details
存在,但无法访问。

enter image description here

我相信,这个问题与我没有正确键入转换有关。不幸的是,我不知道如何解决这个问题。我如何访问

details

typescript mongoose nestjs
1个回答
0
投票

目前,我找到了一个非常丑陋的解决方案。它有效,但绝对不是解决这个问题的正确方法。如果有人知道更好的解决方案,我非常感谢进一步的建议。

export class SomeService {
  async someHandler(userId) {
    const user = await this.userService.getUserById(userId);

    const action = user.subscriptionHistory.find((h) => {
      if (h.action === SubscriptionAction.Upgrade) {
        // @ts-ignore
        const { details } = h._doc as UpgradeAction;
        return details.oldVersion > 1;
      }
      // @ts-ignore
    })._doc as UpgradeAction;;
  }
}

我直接访问 EmbeddedDocument 的 _doc 属性并将其转换为正确的操作类型。由于 _doc 实际上是不可见的,所以我必须忽略打字稿错误。

© www.soinside.com 2019 - 2024. All rights reserved.