Add support for native enums (#7903)

This commit is contained in:
Harminder Virk
2024-07-02 15:22:09 +05:30
committed by GitHub
parent 0aeba83a66
commit b3236ff31c
3 changed files with 74 additions and 7 deletions

View File

@@ -46,4 +46,52 @@ describe("Enum property", () => {
relationships: [],
})
})
test("use typescript enum as enum property options", () => {
enum Roles {
ADMIN,
WRITER,
EDITOR,
}
const property = new EnumProperty(Roles)
expectTypeOf(property["$dataType"]).toEqualTypeOf<Roles>()
expect(property.parse("role")).toEqual({
fieldName: "role",
dataType: {
name: "enum",
options: {
choices: ["ADMIN", "WRITER", "EDITOR", 0, 1, 2],
},
},
nullable: false,
indexes: [],
relationships: [],
})
})
test("use typescript enum with key-value pair as enum property options", () => {
enum Roles {
ADMIN = "admin",
WRITER = "writer",
EDITOR = "editor",
}
const property = new EnumProperty(Roles)
expectTypeOf(property["$dataType"]).toEqualTypeOf<Roles>()
expect(property.parse("role")).toEqual({
fieldName: "role",
dataType: {
name: "enum",
options: {
choices: ["admin", "writer", "editor"],
},
},
nullable: false,
indexes: [],
relationships: [],
})
})
})

View File

@@ -6,7 +6,7 @@ import { ArrayProperty } from "./properties/array"
import { BigNumberProperty } from "./properties/big-number"
import { BooleanProperty } from "./properties/boolean"
import { DateTimeProperty } from "./properties/date-time"
import { EnumProperty } from "./properties/enum"
import { EnumLike, EnumProperty } from "./properties/enum"
import { IdProperty } from "./properties/id"
import { JSONProperty } from "./properties/json"
import { NumberProperty } from "./properties/number"
@@ -291,7 +291,7 @@ export class EntityBuilder {
*
* @customNamespace Property Types
*/
enum<const Values extends unknown>(values: Values[]) {
enum<const Values extends unknown[] | EnumLike>(values: Values) {
return new EnumProperty<Values>(values)
}

View File

@@ -1,19 +1,38 @@
import { BaseProperty } from "./base"
export type EnumLike = {
[K: string]: string | number
[number: number]: string
}
/**
* The EnumProperty is used to define a property with pre-defined
* list of choices.
*/
export class EnumProperty<
const Values extends unknown
> extends BaseProperty<Values> {
const Values extends unknown[] | EnumLike
> extends BaseProperty<
Values extends EnumLike ? Values[keyof Values] : Values[number]
> {
protected dataType: {
name: "enum"
options: { choices: Values[] }
options: {
choices: any[]
}
}
constructor(values: Values[]) {
constructor(values: Values) {
super()
this.dataType = { name: "enum", options: { choices: values } }
if (Array.isArray(values)) {
this.dataType = {
name: "enum",
options: { choices: values },
}
} else {
this.dataType = {
name: "enum",
options: { choices: Object.values(values) },
}
}
}
}