question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

tsoa spec-and-routes fails on reference types referencing large union types

See original GitHub issue

Sorting

  • I’m submitting a …

    • bug report
    • feature request
    • support request
  • I confirm that I

    • used the search to make sure that a similar issue hasn’t already been submit

Expected Behavior

From what I understand, tsoa routes-and-spec should be able to process this controller :

(the code looks a bit stupid, because it was simplified a lot, but I have valid reasons for using this pattern)

// src/controllers/controller.ts
import { Controller, Get, Route, Tags } from 'tsoa'

// with the controller as is, tsoa fails
// if you remove any item in the union type it succeeds

type LargeUnionType =
  { type: 'step-identify' }
  | { type: 'step-add-address' }
  | { type: 'step-verify-address' }
  | { type: 'step-add-naf-code' }
  | { type: 'step-verify-naf-code' }
  | { type: 'step-add-activity' }
  | { type: 'step-add-employee-count' }
  | { type: 'step-add-revenue' }
  | { type: 'step-add-occupation' }
  | { type: 'step-add-surface' }
  | { type: 'step-add-place-extra' }
  | { type: 'step-add-prevention-extra' }
  | { type: 'step-add-email' }

type LargeUnionTypeReference = LargeUnionType['type']

@Tags('Demo')
@Route('demo')
export class DemoController extends Controller {
  @Get('demo')
  async myRoute (): Promise<LargeUnionTypeReference> {
    return 'step-identify'
  }
}

Current Behavior

What happens it that tsoa routes-and-spec fails with this error

npm run tsoa

> reproduce-tsoa-issue@1.0.0 tsoa
> tsoa spec-and-routes

There was a problem resolving type of 'LargeUnionTypeReference'.
Generate routes error.
 Error: Could not determine the keys on any
At: src/controllers/controller.ts:28:28.
This was caused by 'type LargeUnionTypeReference = LargeUnionType['type']'
    at new GenerateMetadataError (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/exceptions.js:22:28)
    at TypeResolver.resolve (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:314:23)
    at TypeResolver.getTypeAliasReference (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:594:353)
    at TypeResolver.getReferenceType (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:569:38)
    at TypeResolver.resolve (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:367:34)
    at TypeResolver.resolve (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:357:118)
    at MethodGenerator.Generate (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/methodGenerator.js:59:76)
    at /home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/controllerGenerator.js:60:58
    at Array.map (<anonymous>)
    at ControllerGenerator.buildMethods (/home/rossille/work/reproduce-tsoa-issue/node_modules/@tsoa/cli/dist/metadataGeneration/controllerGenerator.js:60:14)

Possible Solution

I have no idea how to fix it but I debugged a little bit, and I realized that the issue is triggered by the number of items of the union type generated by LargeUnionType['type']

If I remove any of the options, it works.

Also, I troubleshooted a little bit, and I found that the original cause of the failure is this exception :

Error: No declarations found for referenced type ... 4 more ....
    at new GenerateMetadataError (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/exceptions.js:22:28)
    at TypeResolver.getModelTypeDeclaration (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:715:19)
    at TypeResolver.typeArgumentsToContext (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:844:32)
    at TypeResolver.getReferenceType (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:557:14)
    at TypeResolver.resolve (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:372:34)
    at /home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:116:95
    at Array.map (<anonymous>)
    at TypeResolver.resolve (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:115:45)
    at TypeResolver.resolve (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:314:177)
    at TypeResolver.getTypeAliasReference (/home/rossille/work/orus-monorepo/api/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:600:353)

And upon digging further, I saw that the problems happens when getModelTypeDeclaration manipulates this object :

IdentifierObject {
  pos: -1,
  end: -1,
  flags: 8,
  modifierFlagsCache: 0,
  transformFlags: 0,
  parent: undefined,
  kind: 79,
  originalKeywordKind: undefined,
  escapedText: '... 4 more ...'
}

At this point I stopped, because I don’t know how to go on from here.

Steps to Reproduce

I created a minimal repo to reproduce this issue, it’s here.

To reproduce :

git clone git@github.com:orus-tech/reproduce-tsoa-issue.git
cd reproduce-tsoa-issue
npm install
npm run tsoa

Context (Environment)

Version of the library: 3.14.1 Version of NodeJS: 16.13.1

  • Confirm you were using yarn not npm: [ ] No, I used NPM to install TSOA (but I’m an end user, I’m not working on tsoa itself)

Detailed Description

N/A

Breaking change?

N/A

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
rossillecommented, Feb 9, 2022

Sorry I don’t confirm 😦 Hi, upgraded my test repo version to v4.0.0-beta.0 The issue remains

0reactions
rossillecommented, Feb 10, 2022

You’re welcome. Please let me know if there is anything I can do to help !

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript union and intersection give unintuitive and wrong ...
Ultimately your Animal type is a huge awful union, and if you assign a value that matches none of those, the compiler is...
Read more >
Unions and interfaces - Apollo GraphQL Docs
Unions and interfaces are abstract GraphQL types that enable a schema field to return one of multiple object types. Union type.
Read more >
Designing with types: Single case union types
We can do it using single case union types, like so: type EmailAddress = EmailAddress of string type ZipCode = ZipCode of string...
Read more >
Union type - Wikipedia
In computer science, a union is a value that may have any of several representations or ... types may be stored in its...
Read more >
Handbook - Unions and Intersection Types - TypeScript
That means that we can call it with an argument that's neither a number nor a string , but TypeScript will be okay...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found