Mongoose Populate 的严格类型化

huangapple go评论80阅读模式
英文:

Strict Typing for Mongoose Populate

问题

有没有办法定义/修改一个接口或类型,以断言在使用Mongoose的TypeScript中文档将会被填充?

例如:

interface ISchool {
   name: string;
   address: string; // 修正:应为冒号
}
interface IPerson {
   name: string;
   school?: PopulatedDoc<ISchool & Document>;
}
const PersonSchema: Schema<IPerson> = new Schema<IPerson>({
    name: { type: String },
    school: { type: Schema.Types.ObjectId, ref: 'School' }
})
const Person = mongoose.model<IPerson>('Person', PersonSchema);
export default Person

然后基本上,如果我们与一个Person文档交互,就没有办法知道school属性是否被填充了。
例如:

const person = await Person.findOne({});
if (person.school) { . . . } // `school`是一个ObjectId还是一个Document?

const person = await Person.findOne({}, undefined, { populate: { path: 'school', model: 'School' } });
if (person.school) { . . . } // `school`是一个ObjectId还是一个Document?

有没有办法断言文档属性已经被填充?

谢谢

英文:

Is there any way to define / amend an interface or type as to assert that a document will be populate in typescript using mongoose?

e.g.

interface ISchool {
   name: string;
   address; string;
}
interface IPerson {
   name: string;
   school?: PopulatedDoc&lt;ISchool &amp; Document&gt;
}
const PersonSchema: Schema&lt;IPerson&gt; = new Schema&lt;IPerson&gt;({
    name: { type: String },
    school: { type: Schema.Types.ObjectId, ref: &#39;School&#39; }
})
const Person = mongoose.model&lt;IPerson&gt;(&#39;Person&#39;, PersonSchema);
export default Person

Then essentially if we ever interact with a Person document, there is no way of knowing if the school property is populated of not.
eg.

const person = await Person.findOne({});
if (person.school) { . . . } // is `school` an ObjectId or a Document?

and

const person = await Person.findOne({}, undefined, { populate: { path: &#39;school&#39;, model: &#39;School&#39;} });
if (person.school) { . . . } // is `school` an ObjectId or a Document?

Is there any way to assert that a document property has been populated?

Thanks

答案1

得分: 1

populate-with-typescript文档中,我们可以:

populate()中添加一个泛型参数Paths

import mongoose, { Types } from 'mongoose';

interface ISchool {
	name: string;
	address: string;
}
interface IPerson {
	name: string;
	school?: Types.ObjectId;
}
const PersonSchema: mongoose.Schema<IPerson> = new mongoose.Schema<IPerson>({
	name: { type: String },
	school: { type: mongoose.Schema.Types.ObjectId, ref: 'School' },
});

const Person = mongoose.model<IPerson>('Person', PersonSchema);

(async function run() {
	const person1 = await Person.findOne({});
	person1?.school; // school is ObjectId

	const person2 = await Person.findOne({}).populate<{ school: ISchool }>({ path: 'school', model: 'School' });
	person2?.school; // scholl is ISchool
})();
英文:

From the populate-with-typescript documentation, we can:

> add a generic parameter Paths to the populate()

import mongoose, { Types } from &#39;mongoose&#39;;

interface ISchool {
	name: string;
	address: string;
}
interface IPerson {
	name: string;
	school?: Types.ObjectId;
}
const PersonSchema: mongoose.Schema&lt;IPerson&gt; = new mongoose.Schema&lt;IPerson&gt;({
	name: { type: String },
	school: { type: mongoose.Schema.Types.ObjectId, ref: &#39;School&#39; },
});

const Person = mongoose.model&lt;IPerson&gt;(&#39;Person&#39;, PersonSchema);

(async function run() {
	const person1 = await Person.findOne({});
	person1?.school; // school is ObjectId

	const person2 = await Person.findOne({}).populate&lt;{ school: ISchool }&gt;({ path: &#39;school&#39;, model: &#39;School&#39; });
	person2?.school; // scholl is ISchool
})();

huangapple
  • 本文由 发表于 2023年6月29日 04:30:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76576520.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定