【问题标题】:Enums not working with nestjs and graphql枚举不适用于 nestjs 和 graphql
【发布时间】:2019-08-31 01:34:54
【问题描述】:

我最近从直接使用 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。例如,我的数据库返回 1 的 accountState 应该是 SUSPENDED 我收到一个 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

干杯, 标记

【问题讨论】:

  • 你试过用标准的 typeorm 声明替换自定义枚举装饰器吗?
  • 我已经更新了我的问题,感谢您的回复@shusson

标签: enums graphql nestjs typeorm typegraphql


【解决方案1】:

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

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

这导致将字符串值存储在数据库中,而不是与 graphql 配合得很好。这在以前肯定有效,我不确定如何:) 从数据库设计的角度来看,我更喜欢使用数值,所以任何想法仍然会受到赞赏。

【讨论】:

  • 你太棒了..我只是错过了 registerEnumType(),我使用的是字符串 Enums,但是它不起作用,我看到了你的代码和 BAM....我得到了提示...在我的情况下,具有数值的枚举也可以工作..只需使用带有 int 枚举的接口声明猫鼬文档。
  • 谢谢,很高兴我能帮上忙 :)
  • 我在 nestjs/graphql pkg 中使用 @Field 装饰器。尝试将 defaultValue 设置为包含枚举成员的数组...graphql 操场引发错误,指出"each value in ... must be a valid enum value"。只有在将枚举成员设置为等于其等效字符串之后,才不再出现错误...您的解决方案帮助解决了我的问题。谢谢。
猜你喜欢
  • 2021-11-09
  • 1970-01-01
  • 2021-04-13
  • 2023-03-23
  • 1970-01-01
  • 2018-11-21
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多