Skip to content

Comments

feat: add createElysia factory helper to preserve prefix literal types#1726

Open
shisashi wants to merge 1 commit intoelysiajs:mainfrom
shisashi:fix/factory-type-inference
Open

feat: add createElysia factory helper to preserve prefix literal types#1726
shisashi wants to merge 1 commit intoelysiajs:mainfrom
shisashi:fix/factory-type-inference

Conversation

@shisashi
Copy link

@shisashi shisashi commented Feb 8, 2026

Summary

  • Add createElysia<const P>() — a type-safe factory function that preserves the literal prefix type via const generic inference
  • Add type-level test verifying that factory-created sub-apps produce independent response types when composed via .group() + .use()

Closes #1725

Motivation

When multiple Elysia sub-apps are created via a plain (non-generic) factory function and composed under .group() via .use(), the BasePath generic widens to string. This causes CreateEden to produce index signatures ({ [x: string]: ... }) instead of literal keys, and TypeScript's & intersection merges all response types together.

createElysia is a thin wrapper that preserves the literal type:

import { createElysia, t } from 'elysia'

// ✅ Prefix literal '/sessions' is preserved — no type intersection
const sessionsApp = createElysia({ prefix: '/sessions' })
  .get('/', () => ({ sessions: [] }), {
    response: t.Object({ sessions: t.Array(t.String()) })
  })

See issue #1725 for the full root cause analysis.

Test plan

  • tsc --project tsconfig.test.json passes (including the new type test)
  • Verify the new export is available: import { createElysia } from 'elysia'

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced a factory function that simplifies creation of Elysia sub-applications with improved type safety. Using const generics, it preserves literal base path type information, enabling type-safe composition of multiple sub-apps while maintaining response type independence.
  • Tests

    • Added comprehensive tests verifying type safety and response type independence when composing factory-created sub-applications with different base paths.

When sub-apps are created via a non-generic factory function
(e.g. `const create = (opts?) => new Elysia(opts)`), the `const`
generic inference for `BasePath` is lost — the prefix widens to
`string`, producing index signatures in `CreateEden` that cause
response types to intersect when multiple plugins are composed
via `.use()`.

`createElysia` is a thin generic wrapper around `new Elysia()` that
preserves the literal prefix type, giving users a drop-in replacement
for the common factory pattern.

Closes elysiajs#1725

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 8, 2026

Walkthrough

A new type-safe factory function createElysia is introduced that uses a const generic to preserve literal BasePath types, enabling safer composition of sub-apps. The factory instantiates Elysia with the provided configuration while maintaining type precision during nested app composition.

Changes

Cohort / File(s) Summary
Factory Function Export
src/index.ts
Adds new public createElysia factory function with const generic BasePath extends string = '' that instantiates and returns a type-safe Elysia instance, preserving literal path types for safer sub-app composition.
Type Safety Tests
test/types/index.ts
Adds test scenarios for the new createElysia factory, verifying that independently created sub-apps with prefixes maintain independent response types when composed under a parent route without intersection.

Possibly related issues

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

Hop into type-safe composition, friend! 🐰
With const generics, the types never bend,
Sub-apps compose without fear of intersection,
The factory ensures prefect perfection! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a factory helper function to preserve prefix literal types, which is the core objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉


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.

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.

Factory-created sub-apps cause response type intersection in ~Routes

2 participants