我最近从使用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应该是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
干杯,马克
最后,我通过使枚举等于它们的字符串等效而不是默认数值来定义它们,如下所示:
export enum AccountState {
ACTIVE='ACTIVE',
SUSPENDED='SUSPENDED',
CLOSED='CLOSED',
}
这导致将字符串值存储在数据库中,而不是与graphql一起使用。这肯定以前工作过,我不确定如何:)我更喜欢从数据库设计角度使用数值,所以任何想法仍然会受到赞赏。