Skip to content

Conversation

@wvq
Copy link

@wvq wvq commented Oct 22, 2025

The existing t.Enum() has limitations when handling numeric enums in query parameters: since query values are inherently strings, direct use with numeric enums causes type mismatches (string vs. number) during validation.

But using t.Numeric() loses enum-specific type hints.

This PR adds t.NumericEnum() , transform 'string' to 'number' and validate, as t.Numeric() does.

enum Gender {
  MALE = 1,
  FEMALE = 2,
  UNKNOWN = 3,
}

const app = new Elysia().get("/", ({ query }) => query, {
  query: t.Object({
    // using t.Numeric() will lost enum type info
    gender: t.Numeric(),

    // using t.Enum() can not pass the validation
    gender: t.Enum(Gender),

    // using t.NumericEnum() keep type info and pass the validation
    gender: t.NumericEnum(Gender),
  }),
});

const res = await app.handle(req(`/?name=sucrose&gender=${Gender.MALE}`));

Summary by CodeRabbit

  • New Features

    • Added numeric enum support to the type system for validating numeric enumeration values in schemas and query parameters, accepting both numeric values and their string representations.
  • Tests

    • Added comprehensive test coverage for numeric enum validation in query parameters and schema transform detection.

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

Walkthrough

Introduces NumericEnum support to the Elysia type system, enabling validation and type-safe handling of numeric enums. Adds a new NumericEnum method to ElysiaType with corresponding public API exposure, defines AssertNumericEnum type constraints, and includes test coverage for transform detection and query validation.

Changes

Cohort / File(s) Summary
Type System Enhancement
src/type-system/index.ts
Adds NumericEnum<T>() method to ElysiaType class and exposes it on the public t object to create numeric-enum-aware schemas that validate numeric values or numeric-string forms and return TEnum<T> instances.
Type Constraints
src/type-system/types.ts
Introduces AssertNumericEnum<T> exported type that maps enum keys: numeric and numeric-string keys → string type, string keys → number type, others → never type.
Transform Detection Test
test/aot/has-transform.test.ts
Adds test case verifying that hasTransform() correctly identifies NumericEnum transforms within schemas.
Query Validator Test
test/validator/query.test.ts
Adds test case "parse numeric enum" validating that numeric enum query parameters are correctly parsed and return the corresponding enum value.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

The changes introduce a focused, self-contained feature with straightforward type system additions and corresponding test cases. The implementation follows established patterns, involves no complex logic density, and the homogeneous nature of changes (type definition + method addition + matching tests) requires minimal review reasoning per file.

Poem

🐰 A numeric enum hops into view,
Validating strings and numbers true,
With types that map and constraints align,
The schema dances in perfect design! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: add t.NumericEnum() for numeric enum query handling" is fully related to the main changes in the changeset. The changeset introduces a new NumericEnum capability to the type system (in src/type-system/index.ts and src/type-system/types.ts) and adds tests to verify this functionality, which is exactly what the title describes. The title is concise, specific, and clearly identifies the primary addition without being vague or overly broad. A teammate reviewing the commit history would immediately understand that this PR adds a new helper for numeric enum query validation.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/type-system/types.ts (1)

242-250: Consider adding documentation for the AssertNumericEnum type.

The AssertNumericEnum type uses complex conditional mapping to validate numeric enum structures. Adding a JSDoc comment explaining its purpose and how it handles TypeScript numeric enum forward/reverse mappings would improve maintainability.

+/**
+ * Type constraint for numeric enums that validates the enum structure.
+ * TypeScript numeric enums generate both forward mappings (name -> value) 
+ * and reverse mappings (value -> name) at runtime.
+ * 
+ * @example
+ * enum Gender { MALE = 1, FEMALE = 2 }
+ * // Runtime: { MALE: 1, FEMALE: 2, 1: "MALE", 2: "FEMALE" }
+ */
 export type AssertNumericEnum<T extends Record<string, string | number>> = {
test/validator/query.test.ts (1)

145-167: Consider adding test cases for error scenarios.

The test correctly validates the happy path for numeric enum parsing. Consider adding test cases for:

  • Invalid enum values (e.g., gender=999)
  • Non-numeric strings (e.g., gender=invalid)
  • Missing enum values

This would ensure comprehensive coverage of NumericEnum validation behavior.

Example additional test:

it('reject invalid numeric enum', async () => {
	enum Gender {
		MALE = 1,
		FEMALE = 2,
		UNKNOWN = 3
	}

	const app = new Elysia().get('/', ({ query }) => query, {
		query: t.Object({
			name: t.String(),
			gender: t.NumericEnum(Gender)
		})
	})
	const res = await app.handle(req(`/?name=sucrose&gender=999`))

	expect(res.status).toBe(422)
})
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 272460a and de9f4bf.

📒 Files selected for processing (4)
  • src/type-system/index.ts (4 hunks)
  • src/type-system/types.ts (1 hunks)
  • test/aot/has-transform.test.ts (1 hunks)
  • test/validator/query.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
test/aot/has-transform.test.ts (1)
src/schema.ts (3)
  • hasTransform (292-338)
  • hasTransform (1105-1109)
  • hasTransform (1382-1386)
test/validator/query.test.ts (1)
test/utils.ts (1)
  • req (1-2)
src/type-system/index.ts (2)
src/type-system/types.ts (1)
  • AssertNumericEnum (242-250)
src/type-system/utils.ts (1)
  • compile (38-73)
🔇 Additional comments (5)
test/aot/has-transform.test.ts (1)

101-108: LGTM!

The test correctly verifies that hasTransform detects the NumericEnum schema as having a transform, following the established pattern of other transform detection tests.

src/type-system/index.ts (4)

23-25: LGTM!

The TEnum import is correctly added to support the return type of the NumericEnum function.


44-46: LGTM!

The AssertNumericEnum import is correctly added and used as a type constraint in the NumericEnum function.


156-171: Verify the stricter error handling is intentional.

The NumericEnum decode function always throws an error when the value is NaN or invalid, whereas the Numeric function (lines 127-154) returns the original value if NaN:

// Numeric (line 145)
if (isNaN(number)) return value

// NumericEnum (line 166)
if (isNaN(number)) throw compiler.Error(number)

This stricter validation is likely appropriate for enum values (which must be valid enum members), but it differs from the Numeric pattern. Confirm this is the intended behavior.


629-629: LGTM!

The public API export is correctly added, following the established pattern for other type system utilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant