Skip to content

Conversation

mathfalcon
Copy link

@mathfalcon mathfalcon commented Jul 19, 2025

All Submissions:

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • Have you written unit tests?
  • Have you written unit tests that cover the negative cases (i.e.: if bad data is submitted, does the library respond properly)?
  • This PR is associated with an existing issue?

Closing issues

This closesissue #1256 which specifically mentions Zod's z.infer type support.

If this is a new feature submission:

  • Has the issue had a maintainer respond to the issue and clarify that the feature is something that aligns with the goals and philosophy of the project?

Test plan

WIP


Problem

TSOA fails to process complex types like Zod's z.infer types and other generic type references, causing errors during route generation. This affects:

  1. Return types: TypeError: Cannot read properties of undefined (reading 'kind') when processing generic return types
  2. Query parameters: @Queries() only support 'refObject' or 'nestedObjectLiteral' types when using Zod inferred types

Related Issue: This addresses issue #1256 which specifically mentions Zod's z.infer type support.

Root Cause

The TypeResolver class was not properly handling cases where:

  • Built-in types (like Date) don't have declarations in user code
  • Inline object types in generic type arguments don't have named declarations
  • Complex type references (like z.infer<typeof Schema>) aren't resolved to their underlying object structure

Solution

I implemented a two-part fix:

1. Enhanced TypeResolver (typeResolver.ts)

  • Fixed getModelTypeDeclarations: Added graceful handling for built-in types that don't have user code declarations
  • Improved calcRefTypeName: Added proper handling for inline object types in generic type arguments
  • Enhanced typeArgumentsToContext: Added error handling for cases where type declarations are empty

2. Enhanced ParameterGenerator (parameterGenerator.ts)

  • Improved getQueriesParameters: Added fallback resolution for complex types that don't initially resolve to refObject or nestedObjectLiteral
  • Added type resolution retry: When initial resolution fails, attempts deeper type resolution for TypeReferenceNode types
  • Maintained validation: Still enforces the same type requirements, just with better resolution

Testing

  • ✅ All existing functionality continues to work
  • ✅ Zod z.infer types now work with @Queries() decorator
  • ✅ Generic return types (like PaginatedResponse<T>) now work
  • ✅ Built-in types like Date are handled gracefully
  • ✅ Backward compatibility maintained
  • WIP: will create unit/integration tests for these changes

Use Case Context

This fix was developed to support a specific but common use case:

My Setup: Kysely (auto-generates TypeScript types from DB queries) → Repository methods (strongly typed) → Services → Controllers → TSOA → OpenAPI spec → Frontend TypeScript types

The Problem: Kysely generates complex generic types that TSOA couldn't process (same issue as zod), breaking the type safety chain from database to frontend.

The Solution: This fix enables TSOA to properly resolve complex types, completing the full-stack type safety circle.

Important Notes

  • AI-Assisted Development: This fix was primarily developed using AI assistance. Please review carefully and request changes if needed.
  • Conservative Approach: The fix maintains all existing validation and only enhances type resolution where it was failing
  • Graceful Fallback: If enhanced resolution fails, the system falls back to original behavior with helpful logging
  • Limited Scope: Only affects TypeReferenceNode types that weren't resolving properly

Potential Side Effects

  • Positive: May help other type libraries that use similar patterns to Zod
  • Neutral: All existing valid use cases continue to work exactly as before
  • Monitoring: Added logging to help debug any resolution failures (I didn't found any specific logging mechanism in the repo so let me know what's the right approach here)

Files Changed

  • packages/cli/src/metadataGeneration/typeResolver.ts
  • packages/cli/src/metadataGeneration/parameterGenerator.ts

Impact

This fix enables TSOA to work seamlessly with modern TypeScript patterns and popular libraries like Zod, making it more robust for real-world applications that rely on complex type systems.


Note: Even if this PR isn't approved, the fix works for my specific use case and maintains backward compatibility, so it can be applied locally if needed.

Screenshots

Notice how PaginationQuery is a zod infered type, and the return type of the service is a Kysely autogenerated type.
image
image

🎉 The swagger docs work properly
image

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Hello there mathfalcon 👋

Thank you and congrats 🎉 for opening your first PR on this project.✨

We will review the following PR soon! 👀

@mathfalcon mathfalcon changed the title Feat support zod infer type feat: support zod infer type and complex generic types for decorators and responses Jul 19, 2025
@SpinBoxx
Copy link

SpinBoxx commented Aug 6, 2025

Hello
How can we test this ?

@WoH
Copy link
Collaborator

WoH commented Aug 9, 2025

I'd love to see this in a test as well. So we can't accidentally break this in the future

@mathfalcon
Copy link
Author

hey all, just came back from vacation, will work on tests as soon as I can

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.

3 participants