如何在NestJS模块中高效实现Mongoose鉴别器类型推断?
NestJS + Mongoose鉴别器类型推断问题
我正在开发一个NestJS模块,旨在通过Mongoose的鉴别器(discriminators)将各类通知存储在同一张表中。为简化代码并完全依赖TypeScript的类型推断,我刻意避免使用as关键字,但在实现所需的类型收窄和推断时遇到了阻碍。尽管Mongoose的类型设计看似完备,我仍无法让类型推断按预期工作,希望能获得管理鉴别器类型的有效指导。
核心代码示例
import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { HydratedDocument, Model, Types } from 'mongoose'; import { ISampleAssignedNotification, ITowLogChangeNotification, TNotification, } from './notification.type'; import { Notification } from './schema/notification.schema'; @Injectable() export class NotificationService { constructor( @InjectModel(Notification.name) private notificationModel: Model<TNotification>, @InjectModel('TowLogChange') private towLogChangeModel: Model<ITowLogChangeNotification>, @InjectModel('SampleAssigned') private sampleAssignedModel: Model<ISampleAssignedNotification>, ) {} async testA() { const doc = await this.createA({ userId: new Types.ObjectId(), type: 'TowLogChange', metadata: { towId: new Types.ObjectId(), newStatus: 'some status', }, } as ITowLogChangeNotification); console.log(doc.metadata.towId); } async createA<T extends TNotification>(notification: T) { return this.notificationModel.create(notification) as Promise< HydratedDocument<T> >; } async testB() { const doc = await this.createB({ userId: new Types.ObjectId(), type: 'TowLogChange', metadata: { towId: new Types.ObjectId(), newStatus: 'some status', }, } as ITowLogChangeNotification); // towId 无法被类型识别 // console.log(doc.metadata.towId); // 写法过于繁琐,类型无法像testA那样自动推断 console.log( (doc as HydratedDocument<ITowLogChangeNotification>).metadata.towId, ); } async createB<T extends TNotification>(notification: T) { if (notification.type == 'TowLogChange') { return this.towLogChangeModel.create(notification); } else if (notification.type == 'SampleAssigned') { return this.sampleAssignedModel.create(notification); } throw new Error('Unpredictable logic place.'); } }
简化问题复现
type TLetterA = 'a'; type TLetterB = 'b'; type TLetters = TLetterA | TLetterB; const letterA: TLetterA = 'a'; const letterB: TLetterB = 'b'; const letterAorB: TLetters = letterA; function passLetter<T extends TLetters>(letter: T): T { if (letter == 'a') { return letter } else if (letter == 'b') { return letter; } throw new Error('Some error....'); } const passLetterA = passLetter(letterA); // ^? 期望类型为TLetterA,但实际推断为TLetters
内容的提问来源于stack exchange,提问作者Victor Shelepen
相关产品推荐
相关产品推荐

