Repository navigation
feat(cli): infer procedure output type from resolver return type - #112
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
KevinEdry
force-pushed
the
feat/infer-output-from-return-type
branch
from
June 17, 2026 22:31
c944dec to
77e0947
Compare
When a @Query/@Mutation/@subscription has no explicit `output` schema, the generator now infers the procedure's output type from the resolver method's return type via `ReturnType<>`, instead of falling back to `any`. This brings nestjs-trpc closer to native tRPC ergonomics and removes the need to duplicate service return types as decorator schemas. Closes #106 The generated file imports the router class with `import type` and casts the placeholder resolver to `Awaited<ReturnType<RouterClass["method"]>>`, deferring inference to the consumer's tsc. This works through arbitrary business logic and resolves referenced types transitively without the CLI needing a type checker. Behavior: - Explicit `output` schema always takes priority (unchanged). - Inference only applies to named-export routers; non-exported and default-exported routers fall back to `any` since they can't be referenced by name from the generated file. - Runtime is unchanged: tRPC already infers output natively when `.output()` is omitted. Tests: - New `output-inference` fixture + snapshot covering inferred, explicit- override, and object-literal-return cases. - Validation test runs tsc over the generated file to prove the `ReturnType<>` references compile and types flow through. - `non-exported-router` fixture asserts the `any` fallback. - Validation harness now stubs bare-package modules (e.g. `nestjs-trpc`) imported by the transitively type-checked router files. Docs: - Document optional `output` / output inference in routers.mdx, including the caveat that inferred return types must be exported/nameable to keep the generated AppRouter portable under `declaration: true`.
KevinEdry
force-pushed
the
feat/infer-output-from-return-type
branch
from
June 18, 2026 17:51
77e0947 to
d18c1d8
Compare
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #106.
When a
@Query/@Mutation/@Subscriptionhas no explicitoutputschema, the CLI generator now infers the procedure's output type from the resolver method's return type, instead of falling back toany. This brings nestjs-trpc closer to native tRPC ergonomics and removes the need to duplicate service return types as decorator schemas.Approach
The generated file imports the router class with
import typeand casts the placeholder resolver toAwaited<ReturnType<RouterClass["method"]>>:Inference is deferred to the consumer's
tsc, so it works through arbitrary business logic and resolves referenced types transitively — the CLI never needs to be a type checker.import typeis fully erased, so there's no runtime/bundle impact.Behavior
outputschema always wins — existing behavior is unchanged whenoutputis provided.any, since they can't be referenced by name from the generated file..output()is omitted; this only closes the codegen gap for the generatedAppRoutertype.Tests
output-inferencefixture + snapshot covering inferred, explicit-override, and object-literal-return cases.tscover the generated file to prove theReturnType<>references compile and types flow through correctly.non-exported-routerfixture asserts theanyfallback.nestjs-trpc) imported by the router files that are now type-checked transitively.All CLI tests pass; clippy (
-D warnings) and rustfmt are clean.