configService.get<T>('key') 在类型转换和 joi 验证上失败

Que*_*n3r 1 typescript joi nestjs

我为 NestJs REST API 创建了一个自定义配置文件。这是应用程序正在侦听的端口的简单示例。

我有一个包含内容的 .env 文件

SERVER_PORT = 3000
Run Code Online (Sandbox Code Playgroud)

我的配置文件的示例

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as Joi from '@hapi/joi';

@Injectable()
export class ServerConfigService {
  constructor(private readonly configService: ConfigService) {
    const { error } = Joi.object({
      port: Joi.number()
        .port()
        .required(),
    }).validate({ port: this.port });

    if (error) { // no error thrown
      throw error;
    }

    console.log(typeof this.port); // type is string but should be number
  }

  public get port(): number {
    return this.configService.get<number>('SERVER_PORT');
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望端口类型是,number但它仍然是string. 所以我想到了两件事:

  • 我使用泛型类型进行调用,如下this.configService.get<T>('key')所示。为什么它仍然返回一个字符串?我希望进行类型转换。
  • 我使用 joi 进行验证,如此处所述。我预计 joi 会抛出错误。

端口变量可能是一个坏例子,因为 Nest 能够处理字符串类型的端口。但其他部分需要数字,如果配置变量应该是数字但属于字符串类型,则会抛出错误。

我错过了什么?

Jef*_*ado 6

您发现使用的示例ConfigService非常具有误导性。令人误解的是泛型类型参数。您传递给它的类型仅影响返回值的处理方式。实际的运行时类型将是读取时的类型。

NestJs 用于dotenv读取配置文件,所有值都简单地读取为字符串。不进行任何转换。

你应该像这样使用它:

public get port(): number {
  return +this.configService.get('SERVER_PORT');
}
Run Code Online (Sandbox Code Playgroud)

ConfigService 源
dotenv 源