Skip to content

Conversation

@ap0nia
Copy link

@ap0nia ap0nia commented Dec 9, 2025

Solves #1612 by exposing a globally augmentable interface for adding custom error messages, and using string & {} to allow any string while preserving autocomplete for string templates.

Summary by CodeRabbit

  • Improvements

    • Made custom error typings extensible and more type-safe, improving TypeScript inference and compatibility for custom error templates.
  • Documentation

    • Added guidance and examples for extending allowed error values via module augmentation and aligned schema option typings with the new extensible error type.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 9, 2025

Walkthrough

Replaces the fixed union type ElysiaTypeCustomError with an extensible ElysiaTypeCustomErrors interface and an indexed lookup ElysiaTypeCustomError = ElysiaTypeCustomErrors[keyof ElysiaTypeCustomErrors]; adds documentation showing module augmentation and augments @sinclair/typebox's SchemaOptions.error to use the new type.

Changes

Cohort / File(s) Summary
Type system definition & augmentation
src/type-system/types.ts
Added ElysiaTypeCustomErrors interface (default: `(string & {})
Third-party type augmentation
src/type-system/types.ts (declares)
Added declare module '@sinclair/typebox' to set SchemaOptions.error?: ElysiaTypeCustomError.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify module augmentation compiles and merges correctly in consumer projects.
  • Ensure the documentation example for augmenting ElysiaTypeCustomErrors type-checks.
  • Confirm no unintended runtime effects (these are type-only changes).

Possibly related issues

Poem

🐇
I nibbled lines of type and thread,
Wove errors soft where once they spread,
Add your tune, extend my song,
Strings and numbers hop along,
Compile the meadow — carrot-fed 🥕✨

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 title 'feat: allow extending TypeBox errors' clearly and concisely describes the main change: enabling extensibility of TypeBox error types through an augmentable interface.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4634d24 and 9b26256.

📒 Files selected for processing (1)
  • src/type-system/types.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/type-system/types.ts (1)
src/index.ts (2)
  • ElysiaTypeCustomErrorCallback (8142-8142)
  • ElysiaTypeCustomError (8141-8141)
🔇 Additional comments (3)
src/type-system/types.ts (3)

165-174: Excellent extensibility pattern!

The interface + indexed access type pattern is well-designed and follows TypeScript best practices for creating extensible types. The use of string & {} and number & {} correctly preserves autocomplete for literal types while allowing any string or number. The default key maintains backward compatibility with the original union type.


149-164: Verify module path and improve documentation clarity.

The documentation example shows augmenting 'elysia/type-system/types', but users typically import from 'elysia'. Verify this is the correct module path for augmentation against the package.json exports configuration.

Additionally, fix the documentation clarity:

  • Line 153: "The names of keys only used to map to the values" → "The names of keys are only used to map to the values"
  • Line 153: The phrase "unless you globally augment a specific key" is unclear and should be clarified or removed.

220-224: The module augmentation redefines an existing TypeBox property.

The error property already exists in TypeBox's SchemaOptions interface as a string type (e.g., Type.String({ error: "Invalid email" })). This augmentation overrides its type to accept ElysiaTypeCustomError instead. Ensure this type extension is intentional and compatible with TypeBox's existing error handling, especially when schemas are created or validated through TypeBox APIs.


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
Contributor

@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 (1)
src/type-system/types.ts (1)

149-156: Interface-based map cleanly exposes an augmentable custom-error surface

This refactor looks solid: ElysiaTypeCustomErrors as an exported interface plus ElysiaTypeCustomError = ElysiaTypeCustomErrors[keyof ElysiaTypeCustomErrors] keeps the effective default union (string | boolean | number | ElysiaTypeCustomErrorCallback) while enabling consumers to extend the union via interface augmentation. The (string & {}) on the string member is also consistent with the existing FileType pattern and should preserve autocomplete when plugins add template-literal string types while still allowing arbitrary strings.

One optional improvement: consider adding a brief JSDoc comment above ElysiaTypeCustomErrors that shows the intended augmentation pattern, e.g.:

/**
 * Augment this interface to extend allowed values for SchemaOptions['error']:
 *
 * declare module 'elysia' {
 *   interface ElysiaTypeCustomErrors {
 *     myPlugin: 'my.plugin.error' | `my.plugin.${string}`
 *   }
 * }
 */
export interface ElysiaTypeCustomErrors { ... }

That would make the extension story discoverable without needing to read the PR or docs.

Please double-check that your intended augmentation examples type-check as expected in a consumer project (especially around editor autocomplete for string templates).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a480edb and bf6773c.

📒 Files selected for processing (1)
  • src/type-system/types.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/type-system/types.ts (1)
src/index.ts (2)
  • ElysiaTypeCustomErrorCallback (8142-8142)
  • ElysiaTypeCustomError (8141-8141)

Copy link
Contributor

@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 (1)
src/type-system/types.ts (1)

163-168: Consider more descriptive property names for clarity.

The interface property names (string, boolean, number, ElysiaTypeCustomErrorCallback) serve as arbitrary keys in the mapped type pattern. While functional, they could be more descriptive (e.g., stringErrors, booleanErrors, etc.) to clarify their purpose as extension points rather than primitive type names.

However, since the current naming is concise and the pattern works correctly, this is a minor improvement suggestion.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf6773c and 6543728.

📒 Files selected for processing (1)
  • src/type-system/types.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/type-system/types.ts (1)
src/index.ts (2)
  • ElysiaTypeCustomErrorCallback (8142-8142)
  • ElysiaTypeCustomError (8141-8141)
🔇 Additional comments (3)
src/type-system/types.ts (3)

149-162: Excellent documentation for module augmentation.

The JSDoc comment clearly explains how to extend error types and provides a practical example. This will help users understand how to add their own custom error templates.


170-170: Excellent use of indexed type for extensibility.

The indexed lookup pattern ElysiaTypeCustomErrors[keyof ElysiaTypeCustomErrors] correctly enables module augmentation while maintaining backwards compatibility. The resulting union type is equivalent to the original with the added benefit of extensibility.


216-220: No conflict with TypeBox's SchemaOptions interface.

@sinclair/typebox's SchemaOptions does not define an error property, so this augmentation safely extends it without conflicts. The index signature in TypeBox's SchemaOptions ([prop: string]: any) allows this custom property.

Note: TypeBox's recommended approach for custom validation messages is using SetErrorFunction or DefaultErrorFunction rather than a schema-level property, but your augmentation is compatible and functional.

Copy link
Contributor

@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 (1)
src/type-system/types.ts (1)

149-175: Extensible error type design looks solid; consider a small doc clarification

The new ElysiaTypeCustomErrors interface plus ElysiaTypeCustomError = ElysiaTypeCustomErrors[keyof ElysiaTypeCustomErrors] cleanly enables module augmentation while keeping the default union (string & {} | boolean | number | callback) effectively backwards compatible. Using string & {} here is consistent with the rest of the file and should preserve template‑literal autocomplete without restricting arbitrary strings.

One small suggestion: in the JSDoc example, ensure the module specifier in declare module 'elysia/type-system/types' exactly matches the module name that actually exports ElysiaTypeCustomErrors in the published .d.ts. If the public entry point re‑exports this type from 'elysia' (or another path), reflecting that in the example would make augmentation easier for consumers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6543728 and 4634d24.

📒 Files selected for processing (1)
  • src/type-system/types.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/type-system/types.ts (1)
src/index.ts (2)
  • ElysiaTypeCustomErrorCallback (8142-8142)
  • ElysiaTypeCustomError (8141-8141)

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