Enum Types
gqlkit converts TypeScript string literal unions and enums to GraphQL enum types.
String Literal Unions
String literal unions are automatically converted to GraphQL enum types:
/**
* User account status
*/
export type UserStatus = "ACTIVE" | "INACTIVE" | "PENDING";Generates:
"""User account status"""
enum UserStatus {
ACTIVE
INACTIVE
PENDING
}TypeScript Enums
TypeScript string enums are also supported:
export enum UserStatus {
Active = "ACTIVE",
Inactive = "INACTIVE",
Pending = "PENDING",
}Generates:
enum UserStatus {
ACTIVE
INACTIVE
PENDING
}Deprecating Enum Values
Use the @deprecated JSDoc tag to mark enum values as deprecated:
export enum UserStatus {
Active = "ACTIVE",
/**
* @deprecated Use `Inactive` instead
*/
Pending = "PENDING",
Inactive = "INACTIVE",
}For string literal unions, use a separate type with JSDoc:
/**
* User account status
*/
export type UserStatus =
| "ACTIVE"
| /** @deprecated Use INACTIVE instead */ "PENDING"
| "INACTIVE";Generates:
enum UserStatus {
ACTIVE
PENDING @deprecated(reason: "Use INACTIVE instead")
INACTIVE
}Using Enums in Types
export type User = {
id: string;
name: string;
status: UserStatus;
};
export type UpdateUserInput = {
status: UserStatus | null;
};Generates:
type User {
id: String!
name: String!
status: UserStatus!
}
input UpdateUserInput {
status: UserStatus
}Inline Enums
When you define a string literal union or reference a TypeScript enum inline (without exporting it from the schema directory), gqlkit automatically generates a GraphQL enum type. This follows the same pattern as inline objects.
Inline String Literal Unions
String literal unions used directly in field or argument types generate enum types automatically:
export type User = {
id: string;
name: string;
/** Current account status */
status: "active" | "inactive" | "pendingReview";
};Generates:
type User {
id: String!
name: String!
"""Current account status"""
status: UserStatus!
}
enum UserStatus {
ACTIVE
INACTIVE
PENDING_REVIEW
}The generated enum type name follows the convention {ParentTypeName}{PascalCaseFieldName}.
External TypeScript Enums
TypeScript enums defined outside the schema directory are also automatically converted:
// src/types/order.ts (outside schema directory)
/**
* Order status in the system
*/
export enum OrderStatus {
/** Order is pending payment */
Pending = "pending",
/** Order is being processed */
Processing = "processing",
/** Order has been shipped */
Shipped = "shipped",
}
// src/gqlkit/schema/order.ts
import { OrderStatus } from "../../types/order.js";
export type Order = {
id: string;
status: OrderStatus;
};Generates:
type Order {
id: String!
status: OrderStatus!
}
"""Order status in the system"""
enum OrderStatus {
"""Order is pending payment"""
PENDING
"""Order is being processed"""
PROCESSING
"""Order has been shipped"""
SHIPPED
}TSDoc comments on the enum and its values are preserved as GraphQL descriptions. The @deprecated tag is also supported.
When the same external TypeScript enum is referenced in multiple places, gqlkit generates a single GraphQL enum type and reuses it across all references.
Inline Enum Naming Convention
The naming convention for auto-generated enum types matches inline objects:
| Context | Naming Pattern | Example |
|---|---|---|
| Object field | {ParentTypeName}{PascalCaseFieldName} | User.status → UserStatus |
| Input field | {ParentTypeNameWithoutInputSuffix}{PascalCaseFieldName}Input | CreateUserInput.role → CreateUserRoleInput |
| Query/Mutation argument | {PascalCaseFieldName}{PascalCaseArgName}Input | searchUsers(status: ...) → SearchUsersStatusInput |
| Field resolver argument | {ParentTypeName}{PascalCaseFieldName}{PascalCaseArgName}Input | User.posts(filter: ...) → UserPostsFilterInput |
Nullable Inline Enums
Nullable inline enums are supported:
export type User = {
id: string;
status: "active" | "inactive" | null;
};Generates:
type User {
id: String!
status: UserStatus
}
enum UserStatus {
ACTIVE
INACTIVE
}Arrays of Inline Enums
Inline enums in array types are also supported:
export type User = {
id: string;
roles: ("admin" | "editor" | "viewer")[];
};Generates:
type User {
id: String!
roles: [UserRoles!]!
}
enum UserRoles {
ADMIN
EDITOR
VIEWER
}When Enums Are NOT Auto-Generated
If you export a type from the schema directory, it is treated as an explicit type declaration and not auto-generated:
// Exported from schema - used as-is, not auto-generated
export type UserStatus = "active" | "inactive" | "pending";
export type User = {
id: string;
status: UserStatus; // References the exported type
};Inline Enum Payloads
String literal unions in resolver return types generate GraphQL Enum types with the naming convention {ResolverName}Payload:
export const getStatus = defineQuery<NoArgs, "active" | "inactive" | "pending">(
(_root, _args, ctx) => ctx.db.getStatus()
);Generates:
type Query {
getStatus: GetStatusPayload!
}
enum GetStatusPayload {
ACTIVE
INACTIVE
PENDING
}For field resolvers, the naming convention is {ParentTypeName}{PascalCaseFieldName}Payload:
export const status = defineField<User, NoArgs, "online" | "offline" | "away">(
(parent) => parent.currentStatus
);Generates:
type User {
status: UserStatusPayload!
}
enum UserStatusPayload {
ONLINE
OFFLINE
AWAY
}See Queries & Mutations for more details on inline payload types.
Automatic Case Conversion
gqlkit automatically converts enum values to SCREAMING_SNAKE_CASE format, which is the GraphQL convention:
export type UserStatus = "active" | "inProgress" | "pending_review" | "on-hold";Generates:
enum UserStatus {
ACTIVE
IN_PROGRESS
PENDING_REVIEW
ON_HOLD
}When conversion changes the original value, gqlkit generates resolver mappings to translate between GraphQL and TypeScript values:
// Generated resolvers.ts
export function createResolvers() {
return {
UserStatus: {
ACTIVE: "active",
IN_PROGRESS: "inProgress",
PENDING_REVIEW: "pending_review",
ON_HOLD: "on-hold",
},
};
}If values are already in SCREAMING_SNAKE_CASE, no resolver mapping is generated.
Automatic Prefix Stripping
When all enum values share a common prefix that matches the enum name, gqlkit automatically strips the prefix to produce cleaner GraphQL values:
export type UserStatus = "USER_STATUS_ACTIVE" | "USER_STATUS_INACTIVE" | "USER_STATUS_PENDING";Generates:
enum UserStatus {
ACTIVE
INACTIVE
PENDING
}This works with various naming conventions:
| TypeScript Enum | Values | Generated GraphQL Values |
|---|---|---|
UserStatus | USER_STATUS_ACTIVE, USER_STATUS_INACTIVE | ACTIVE, INACTIVE |
orderStatus | ORDER_STATUS_PENDING, ORDER_STATUS_SHIPPED | PENDING, SHIPPED |
Status | STATUS_ACTIVE, STATUS_INACTIVE | ACTIVE, INACTIVE |
Prefix stripping is not applied when:
- Not all values share the common prefix
- Stripping would result in an empty value (e.g.,
USER_STATUS_forUserStatus)
When prefix stripping is applied, gqlkit generates resolver mappings to preserve the original TypeScript values:
// Generated resolvers.ts
export function createResolvers() {
return {
UserStatus: {
ACTIVE: "USER_STATUS_ACTIVE",
INACTIVE: "USER_STATUS_INACTIVE",
PENDING: "USER_STATUS_PENDING",
},
};
}Duplicate Value Detection
If multiple TypeScript values convert to the same GraphQL enum value, gqlkit reports a DUPLICATE_ENUM_VALUE_AFTER_CONVERSION error:
// Error: 'activeUser' and 'active_user' both convert to ACTIVE_USER
export type Status = "activeUser" | "active_user" | "pending";Invalid Enum Values
Enum values that are not valid GraphQL identifiers are automatically skipped with a warning. gqlkit converts enum values to SCREAMING_SNAKE_CASE, and the converted name must:
- Match the pattern
/^[_A-Za-z][_0-9A-Za-z]*$/ - Not start with
__(reserved for GraphQL introspection)
String Literal Unions
export type Status =
| "active" // ✅ Converts to ACTIVE
| "inProgress" // ✅ Converts to IN_PROGRESS
| "0pending" // ⚠️ Skipped: converts to 0PENDING (starts with number)
| "__internal"; // ⚠️ Skipped: converts to __INTERNAL (starts with __)Generates:
enum Status {
ACTIVE
IN_PROGRESS
}TypeScript Enums
export enum Priority {
HIGH = "HIGH", // ✅ Valid
MEDIUM = "MEDIUM", // ✅ Valid
LOW = "LOW", // ✅ Valid
"0INVALID" = "0INVALID", // ⚠️ Skipped: starts with number
__RESERVED = "__RESERVED", // ⚠️ Skipped: starts with __
}Generates:
enum Priority {
HIGH
MEDIUM
LOW
}When enum values are skipped, gqlkit outputs a warning with the original name, converted name, and location.