Допустим, у меня есть несколько классов, которые имеют похожий метод. В этом случае набор сервисов, имеющих метод saveModel:
public async saveModel(newModel: IModel): Promise<IModel> {
return await newModel.save();
}
Общий метод c, который я создал, выглядит следующим образом:
public async saveModel<P extends Document>(newModel: P): Promise<P> {
return await newModel.save();
}
Все мои сервисы ( те, которые используют этот метод) расширяют класс, который содержит этот обобщенный метод c, поэтому теперь для любой из этих служб я могу вызвать answerService.saveModel(newAnswer)
, и он сохранит ответ. Все было замечательно, пока я не понял, что могу также поместить туда объект типа IQuestion. И объект типа IDinosaur, если я хотел, до тех пор, пока он расширяет интерфейс документа Mon goose.
Есть ли какой-либо способ для меня, чтобы заставить определенные интерфейсы использоваться в каждой службе? Как мне убедиться, что answerService сохраняет только объекты с типом IAnswer? Нужно ли, чтобы answerService реализовывал интерфейс с такой сигнатурой saveModel, например:
interface IAnswerService {
saveModel(newModel: IAnswer): Promise<IAnswer>;
}
Это скелет того, как выглядит все это:
EntityService.ts
import { Document } from 'mongoose';
export class EntityService implements IEntityService {
public async saveModel<P extends Document>(newModel: P): Promise<P> {
try {
const savedModel = await newModel.save();
return savedModel;
} catch (err) {
console.log(err);
return null;
}
}
}
answer.service.ts
import { Answer, IAnswer } from '@models/answer.model';
import { EntityService } from '@classes/EntityService';
class AnswerService extends EntityService {
private static instance: AnswerService;
private constructor() {
super();
}
static getInstance(): AnswerService {
if (!AnswerService.instance) {
AnswerService.instance = new AnswerService();
}
return AnswerService.instance;
}
}
const answerService = AnswerService.getInstance();
export default answerService;
answer.model.ts
import mongoose, { Schema, Document, Model } from 'mongoose';
export interface IAnswer extends Document {
answerText: string;
posterID: string;
}
const AnswerSchema: Schema = new Schema({
answerText: {type: String, required: true},
posterID: {type: String, required: true}
}, {
minimize: false
});
export const Answer: Model<IAnswer> = mongoose.model<IAnswer>('Answer', AnswerSchema);
Все остальные интерфейсы наследуются от того же, что и IAnswer (Модель, Схема, Документ ).
И использование службы ответов в целом выглядит следующим образом:
import answerService from 'answer.service';
import { Answer } from 'answer.model';
const answer = new Answer({
answerText: 'Stuff',
posterID: '123456789'
})
answerService.saveModel(answer);