枚举不适用于nestjs和graphql

时间:2019-04-09 17:28:38

标签: enums graphql nestjs typeorm type-graphql

我最近已经从使用typegraphql和typeorm直接移到将它们与nestjs一起使用。通常,这是一种直接的体验。但是,我有一个关于枚举的问题。

我有一组自定义装饰器,这些装饰器已组合在一起,因此无需typeorm,typegraphql和类验证器装饰器,就可以轻松装饰模型。在枚举以外的所有情况下,此功能以前都很有效,现在可以正常工作。

作为一个示例,这里是一个@OptionalDecimal装饰器:

import { IsNumber } from 'class-validator'
import { Field, Float } from 'type-graphql'
import { Column } from 'typeorm'

export function OptionalDecimal() {
    const typeDecorator = IsNumber()
    const fieldDecorator = Field(type => Float, { nullable: true })
    const columnDecorator = Column('decimal', { nullable: true })

    return (target: any, key: string) => {
        typeDecorator(target, key)
        fieldDecorator(target, key)
        columnDecorator(target, key)
    }
}

我的@Enum装饰器是这样的:

import { IsEnum } from 'class-validator'
import { Field } from 'type-graphql'
import { Column } from 'typeorm'
import { IEnumOptions } from './IEnumOptions'

export function Enum(
    typeFunction: (type?: any) => object,
    options: IEnumOptions = {}
) {
    const isEnumDecorator = IsEnum(typeFunction())
    const fieldDecorator = Field(typeFunction)
    const columnDecorator = Column({
        default: options.default,
        enum: typeFunction(),
        type: 'enum',
    })

    return (target: any, key: string) => {
        isEnumDecorator(target, key)
        fieldDecorator(target, key)
        columnDecorator(target, key)
    }
}

我在单独的文件中定义枚举,如下所示:

import { registerEnumType } from 'type-graphql'

export enum AccountState {
  ACTIVE,
  SUSPENDED,
  CLOSED,
}

registerEnumType(AccountState, { name: 'AccountState' })

因此被使用:

@EntityType()
export class Member extends VersionedEntity {
  @IdentifierNewGuid()
  public readonly id: string

  @Enum(type => AccountState, { default: AccountState.ACTIVE })
  public accountState: AccountState
...

我的数据库返回枚举的数字ID,数据库(mysql)中的字段类型为enum。例如,在我的数据库为accountState返回1应该被暂停的情况下,我收到graphql错误:

  "errors": [
    {
      "message": "Expected a value of type \"AccountState\" but received: 1",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "searchMembers",
        0,
        "accountState"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Expected a value of type \"AccountState\" but received: 1",
            "    at completeLeafValue

因此,回顾一下这种方法,可以直接与typeorm和typegraphql一起使用,但现在却无法正常工作。我看到的所有其他装饰器都可以正常工作(超过50个),所以这只是枚举所特有的。

这对我来说是一个主要的障碍,由于我目前尚无主意,因此任何帮助将不胜感激。

编辑-作为对Shusson的回应,当我手动添加装饰器时,它实际上也不起作用:

@Column({
    default: AccountState.ACTIVE,
    enum: AccountState,
    type: 'enum',
  })
@Field(type => AccountState)
public accountState: AccountState

干杯, 标记

1 个答案:

答案 0 :(得分:0)

最后,我通过使枚举等于其字符串等效项而不是像这样定义它们时的默认数值来解决此问题:

export enum AccountState {
  ACTIVE='ACTIVE',
  SUSPENDED='SUSPENDED',
  CLOSED='CLOSED',
}

这导致将字符串值存储在数据库中,而该值与graphql很好地配合使用。这肯定在以前起作用,我不确定如何:)从数据库设计的角度来看,我宁愿使用数字值,因此任何想法仍然值得赞赏。