我最近从直接使用 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
干杯, 标记
最佳答案
最后,我通过在定义枚举时使枚举等于其字符串等效项而不是默认数值来解决此问题,如下所示:
export enum AccountState {
ACTIVE='ACTIVE',
SUSPENDED='SUSPENDED',
CLOSED='CLOSED',
}
这会导致将字符串值存储在数据库中,而不是与 graphql 配合良好。这以前肯定有效,我不知道如何:)我更喜欢从数据库设计的角度使用数值,所以任何想法仍然会受到赞赏。
关于typescript - 枚举不适用于 Nestjs 和 graphql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55598213/