带有猫鼬的打字稿:无法读取未定义的属性“CasterConstructor”

Posted

技术标签:

【中文标题】带有猫鼬的打字稿:无法读取未定义的属性“CasterConstructor”【英文标题】:typescript with mongoose: cannot read property 'CasterConstructor' of undefined 【发布时间】:2018-08-18 06:59:24 【问题描述】:

我正在使用 typescript 和 mongoose 编写一个 node.js 应用程序。我正在使用打字稿模型方法,当我调用 create 方法创建新的子文档时,继续收到“无法读取未定义的属性 CasterConstructor”。代码示例如下:

seat.ts:
export let SeatSchema: Schema = new Schema(
    travelerId: type: Schema.Types.ObjectId, required: true,
    seatClass: type: Schema.Types.String, minlength: 5, maxlength:10, required: true, enum: [“FirstClass”, “Coach”],
    row: type: Schema.Types.Number, required: true,
    section: type: Schema.Types.Number, required: true,
    hasBoarded: type: Schema.Types.Boolean, required: false
);


plane.ts:
export let PlaneSchema: Schema = new Schema(
    manufacturer: type: Schema.Types.String, required: true,
    seatsChart: [SeatSchema],
    routeId: [type: Schema.Types.ObjectId, ref: ‘routes’, required: true];

iseat.ts: 
export interface ISeat 
    travelerId: string,
    seatClass: string,
    row: number,
    section: number,
    hasBoarded: boolean



iplane.ts:
export interface IPlane 
    manufacturer: string,
    seatsChart: Types.DocumentArray<ISeatModel>,
    routeId: [string]


iseatmodel.ts:
export interface ISeatModel extends ISeat, Subdocument 


iplanemodel.ts:
export interface IPlaneModel extends IPlane, Document 


planerepository.ts:
constructor(db) 
    this._model: Model<IPlaneModel> = db.model<IPlaneModel>(“Plane”, PlaneSchema);

.
.
.
addNewSeat(planeId: string, seat: ISeat) 
    let plane: IPlaneModel = await this._model.findById(planeId);
    let newSeat: ISeatModel = plane.SeatsChart.create(seatAttributes);
    plane.seatsChart.push(newSeat);
    let planeUpdated: IPlane = await plane.save();

这是我不断收到的错误: TypeError:无法读取未定义的属性“casterConstructor” 在 Array.create (/node_modules/mongoose/lib/types/documentarray.js:236:35) . . . . .

我没有看到我可能会丢失什么。有人可以回顾一下,让我知道我可能会错过什么,以及这是否完全是正确的方法。

更新:改用push后,问题似乎出在/mongoose/lib/types/array.js,_checkManualPopulation:

function _checkManualPopulation(arr, docs) 
  var ref = arr._schema.caster.options && arr._schema.caster.options.ref;
  if (arr.length === 0 &&
      docs.length > 0) 
    if (_isAllSubdocs(docs, ref)) 
      arr._parent.populated(arr._path, [],  model: docs[0].constructor );
    
  

由于某种原因,在调用 push 时未定义 _schema 对象,这会导致异常。我不确定这是一个错误,还是没有调用其他会初始化 _schema 属性的东西?

【问题讨论】:

你看过这里吗? github.com/Automattic/mongoose/issues/5648 没有。我没有看到这篇文章,但我目前使用的是“import mongoose = require("mongoose");”而不是“import * as mongoose from 'mongoose'”。现在,有一个地方我正在使用“import mongoose = require('mongoose')”。那会有什么不同吗? 【参考方案1】:

我不确定您在添加子文档时在做什么? 您应该将其添加为 POJO。

以下代码已经过测试,运行良好。

async function addNewSeat(planeId: string, seat: ISeat) 
  let plane = await PlaneModel.findById(planeId);
  plane.seatChart.push(seat);
  await plane.save();

然后像下面这样调用它:

let plane = await PlaneModel.create(flightNumber:"AR44");
await addNewSeat(plane.id, 
     travelerId:"x", 
     seatClass:"business", 
     row:4, 
     section:9, 
     hasBoarded:true
);
await addNewSeat(plane.id, 
     travelerId:"y", 
     seatClass:"economy", 
     row:42, 
     section:1, 
     hasBoarded:true
);

【讨论】:

【参考方案2】:

我找到了答案。我最终不得不将创建数据库连接的逻辑从单独的库移动到主项目中的 inversify.config.js 文件,并将 mongoose 连接注入每个存储库。这似乎解决了问题。

【讨论】:

以上是关于带有猫鼬的打字稿:无法读取未定义的属性“CasterConstructor”的主要内容,如果未能解决你的问题,请参考以下文章

无法读取未定义猫鼬的属性“长度”

根据打字稿中的请求参数设置猫鼬的查询过滤器

使用带有打字稿的猫鼬创建自定义验证时出错

使用带有打字稿的猫鼬创建自定义验证时出错

如何在打字稿中的猫鼬userschema.methods中使用“this”

无法读取未定义的属性,Typescript