简体   繁体   English

如何列出 Nestjs DTO class 的属性?

[英]How to list properties of a Nestjs DTO class?

I have following Nestjs DTO class:我有以下 Nestjs DTO class:

// create-job-offer.dto.ts
import { IsOptional, IsNumber } from 'class-validator';

export class CreateJobOfferDto {
  @IsNumber()
  @IsOptional()
  mentorId: number;

  @IsNumber()
  @IsOptional()
  companyId: number;
}

I want to obtain the list of class properties: ['mentorId', 'companyId'] .我想获取 class 属性的列表: ['mentorId', 'companyId']

I tried so far in a controller without success following methods:到目前为止,我在 controller 中尝试了以下方法但没有成功:

Object.getOwnPropertyNames(new CreateJobOfferDto());
Object.getOwnPropertyNames(CreateJobOfferDto);

Object.getOwnPropertySymbols(new CreateJobOfferDto());
Object.getOwnPropertySymbols(CreateJobOfferDto);

Object.getOwnPropertyDescriptors(CreateJobOfferDto);
Object.getOwnPropertyDescriptors(new CreateJobOfferDto());

Object.getPrototypeOf(CreateJobOfferDto);
Object.getPrototypeOf(new CreateJobOfferDto());

If I add a method, or vars in a constructor, I can get them, but not the properties.如果我在构造函数中添加方法或变量,我可以获得它们,但不能获取属性。

The reason why I want to achieve this is, I am using Prisma and React, and in my React app I want to receive the list of class properties so that I can generate a model form dynamically.我想要实现这一点的原因是,我正在使用 Prisma 和 React,在我的 React 应用程序中,我想接收 class 属性的列表,以便我可以动态生成 model 表单。

There is no easy direct way to get the list of properties of a DTO class, or more comprehensively, any type of class that has only properties.没有简单直接的方法来获取 DTO class 的属性列表,或者更全面地说,任何类型的 class 只有属性。

The reason is that whenever you defined a property without any values, it becomes disappears after compiling to javascript.原因是每当你定义一个没有任何值的属性时,它在编译到 javascript 后就会消失。

Example:例子:

// typescript
class A {
    private readonly property1: string;
    public readonly property2: boolean;
}

it compiles to this:它编译为:

// javascript
"use strict";
class A {}

In order to achieve this goal, you need to write a custom decorator.为了实现这个目标,你需要写一个自定义装饰器。 like this:像这样:

const properties = Symbol('properties');

// This decorator will be called for each property, and it stores the property name in an object.
export const Property = () => {
  return (obj: any, propertyName: string) => {
    (obj[properties] || (obj[properties] = [])).push(propertyName);
  };
};

// This is a function to retrieve the list of properties for a class
export function getProperties(obj: any): [] {
  return obj.prototype[properties];
}

Imagine I have a DTO class for a user, like this:想象一下,我有一个用户的 DTO class,如下所示:

import { getProperties } from './decorators/property.decorator';

export class UserDto {
  @Property()
  @IsNotEmpty()
  firstName: string;

  @Property()
  @IsEmail()
  @IsOptional()
  public readonly email: string;
}

and I want to get all properties in a list, so we need to call the getProperties method which we defined earlier, so:我想获取列表中的所有属性,因此我们需要调用我们之前定义的getProperties方法,因此:

import { UserDto } from './dtos/user.dto';

getProperties(UserDto); // [ 'firstName', 'email' ]

You can also use an npm module ts-transformer-keys .您还可以使用 npm 模块ts-transformer-keys

A TypeScript custom transformer which enables to obtain keys of given type.一个 TypeScript 自定义转换器,可以获取给定类型的密钥。

How to use:如何使用:

import { keys } from 'ts-transformer-keys';

interface Props {
  id: string;
  name: string;
  age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); // ['id', 'name', 'age']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM