Typescript lint 无法识别类型转换装饰器

Typescript lint doesn't recognize type transform decorator

我正在使用带有 class 验证器的 nestjs 来验证环境变量,configuration.service.ts 从 configService 文件中获取它的值,该文件从 .env 中获取它需要的内容并将其放入 json对象。

在端口和超时属性中,我希望收到一个字符串,因为它来自 .env 文件,装饰器 @Type(() => Number) 将尝试将收到的任何内容转换为数字。就我而言,装饰器仅在函数调用结束时运行,因此函数接受一个字符串和 returns 一个字符串,然后将字符串转换为数字。

问题是属性端口和 connectTimeoutMS 需要一个数字,typescript lint 声称它正在接收一个字符串,看起来它没有识别 cast 装饰器。 我想知道是否有办法解决这个问题,或者我必须放弃 cast 装饰器。

configuration.service.ts

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Type } from 'class-transformer';
import {
    IsBoolean,
    IsDefined,
    IsInt,
    IsNumber,
    IsString,
} from 'class-validator';
import { ValidatedConfigService } from 'src/config/utils/validate.config';
import { DatabaseType, Logger } from 'typeorm';

@Injectable()
export class DatabaseConfigService extends ValidatedConfigService {
    constructor(private configService: ConfigService) {
        super();
    }

    @IsString()
    @IsDefined()
    get type(): DatabaseType {
        return this.configService.get<DatabaseType>('database.type');
    }

    @IsString()
    @IsDefined()
    get host(): string {
        return this.configService.get<string>('database.host');
    }

    @IsInt()   
    @IsDefined()
    @Type(() => Number)
    get port(): string {
        return this.configService.get<string>('database.port');
    }
    
    @IsNumber()   
    @IsDefined()
    @Type(() => Number)
    get timeOut(): string {
        return (
            this.configService.get<string>('database.connectTimeoutMS') ||
            '2000'
        );
    }

    @IsString()
    @IsDefined()
    get entities(): string {
        return this.configService.get<string>('database.entities');
    }

  
}

database.configuration.ts

import { Injectable } from '@nestjs/common';
import { ConnectionOptions } from 'typeorm';
import { DatabaseConfigService } from './configuration.service';

export class DatabaseConfigController {
    constructor(private readonly configService: DatabaseConfigService) {}

    get settings(): ConnectionOptions {
        return {
            type: this.configService.type,
            host: this.configService.host,
            port: this.configService.port,
            connectTimeoutMS: this.configService.timeOut,
            entities: [this.configService.entities],           
        };
    }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,    
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false
  }
}

[编辑 12/20/21]

我不得不放弃使用 @Type() 装饰器,正如 Micael Levi 在他的回答中所说的那样,这一行明确告诉 TSC 期待一个字符串 get timeOut(): string.

所以我必须将它更改为数字,但这样做我还需要将我在函数内部返回的类型更改为任何类型或将其转换为数字。

这种方式会出现明显的类型错误。

    @IsInt()
    @IsDefined()
    get port(): number {       
        return this.configService.get<string>('db.port');
    }

不指定类型不会触发 lint,但在运行时会因 IsInt() 装饰器而引发错误,因为它从 database.configuration.ts

获取字符串
    @IsInt()
    @IsDefined()
    get port(): number {       
        return this.configService.get('db.port');
    }

解决方法是手动将其转换为数字,此转换过程也可以在 database.configuration.ts 中完成。

    @IsInt()
    @IsDefined()
    get port(): number {       
        return parseInt(this.configService.get<string>('db.port'), 10);
    }

也许我以不打算使用的方式使用 @Type() 装饰器,说实话我从来不需要使用它,我只是想使用这个包进行所有验证。

在下一行中,(不是 TS)告诉 TSC this.configService.timeOut 是一个 string

get timeOut(): string

只需将其更改为get timeOut(): number。装饰器不会为您输入任何内容。