NestJS:在*编译时*强制实施服务

NestJS: Enforce implementation of a service at *compile-time*

简而言之:

我有一项服务 - 我们称它为 CatsService...

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
    GetCat(id: number){
        return id + 12345;
    }
}

稍后,模块希望使用此 CatsService 以便将其注入构造函数。它还动态解析这个CatsService

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import * as ProductionCatsService from "./production"
import * as DevelopmentCatsService from "./development"

const catsServiceProvider = {
  provide: CatsService,
  useValue: process.env.NODE_ENV === "development" ? 
    DevelopmentCatsService  :
    ProductionCatsService
}

@Module({
  controllers: [CatsController],
  providers: [catsServiceProvider],
  exports:[CatsService]
})
export class CatsModule {}

这两个 这些服务实现都是严格的。这意味着 /cats/:id 路由 returns:

{"statusCode":500,"message":"Internal server error"}

自从开始写这篇文章以来,我就有了让所有东西都实现 ICatsService 接口的想法。

经过大量摆弄,我构建了一个解决方案:

  1. 我有一个“service_interface”文件,它有一个名为 ICatsInterface 的抽象 class 和一个抽象方法 (GetCat)

  2. 我已经让这些实现中的每一个都实现了这个service_interface。

  3. 我已经让 控制器 使用 ICatsService 而不是 CatsService

我的问题是,现在可以编译了,但出现以下错误:

TypeError: this.catsService.GetCat is not a function
    at CatsController.get (/home/a/learning-nest/src/cats/cats.controller.ts:12:33)
    at /home/a/learning-nest/node_modules/@nestjs/core/router/router-execution-context.js:38:29
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at /home/a/learning-nest/node_modules/@nestjs/core/router/router-execution-context.js:46:28
    at /home/a/learning-nest/node_modules/@nestjs/core/router/router-proxy.js:9:17

我简直不知道该怎么办了。即使我已经编译了它,我也不能让它实际上被迫实现我想要的 interface/abstract class 。我已确保 DevelopmentCatsService 和 ProductionCatsService 都实现了 GetCat。它们都标有 @Injectable。我真的不知道从这里去哪里。

当有人没有实现我想在我的服务中实现的方法时,我是否应该放弃我的编译时错误消息的梦想?

我已经解决了我自己的问题。很简单。

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import * as ProductionCatsService from "./production"
import * as DevelopmentCatsService from "./development"

const catsServiceProvider = {
  provide: CatsService,
  useValue: process.env.NODE_ENV === "development" ? 
    DevelopmentCatsService  :
    ProductionCatsService
}

@Module({
  controllers: [CatsController],
  providers: [catsServiceProvider],
  exports:[CatsService]
})
export class CatsModule {}

在上面的代码片段中,我正在导入“* 作为 ProductionCatsService”。这导致我的 ProductionCatsService 实际上是一个对象,包裹着我想要的真实服务实现!

抱歉打扰大家了。