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.

Generate routes error (IndexedAccessType + TypeOperator)

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

Current Behavior

This is a problem similar to the Enum problem that was improved with this pull request. https://github.com/lukeautry/tsoa/pull/636

For example, if you use the KeyOfKeyword type generated using the object’s key value as the schema, the Generate routes error will occur.

const genderCds: {
    readonly male: "male";
    readonly female: "female";
};

type GenderCd = typeof genderCds[keyof typeof genderCds];

export interface TestModel {
  genderCd: GenderCd;
}
Generate routes error.
 Error: Unknown type: IndexedAccessType
At: /mypath/to/xxx/index.d.ts:8:8.
This was caused by 'type GenderCd = typeof genderCds[keyof typeof genderCds];'
    at new GenerateMetadataError (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/exceptions.js:22:28)
    at TypeResolver.resolve (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:308:19)
    at TypeResolver.getTypeAliasReference (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:529:353)
    at TypeResolver.getReferenceType (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:505:38)
    at TypeResolver.resolve (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:341:34)
    at TypeResolver.resolve (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:294:131)
    at TypeResolver.propertyFromSignature (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:761:143)
    at /mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:727:161
    at Array.map (<anonymous>)
    at TypeResolver.getModelProperties (/mypath/to/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:727:124)

Possible Solution

When parsing a type like GenderCd in this example with the TypeResolver class, ts.isIndexedAccessTypeNode(this.typeNode) is true and ts.isTypeOperatorNode(this.typeNode.indexType) && this.typeNode.indexType.operator === ts.SyntaxKind.KeyOfKeyword is true.

Therefore, I confirmed that it works as expected by resolving indexType as a actual type as shown below.

// ↓added
if (ts.isIndexedAccessTypeNode(this.typeNode)) {
  return new TypeResolver(this.typeNode.indexType, this.current, this.typeNode, this.context, this.referencer).resolve();
}
// ↑added

if (ts.isParenthesizedTypeNode(this.typeNode)) {
...

However, I have no experience with TypeScript type analysis, so I’m not sure if this solution is correct. Is it possible to consider a complete solution?

It’s very useful to dynamically type string literals, so I’d be very happy if this could be resolved.

Thank you.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6

github_iconTop GitHub Comments

7reactions
dgrdlcommented, Aug 25, 2021

I am running into this exact same problem with tsoa 3.9.0 when using enums in Prisma. Prisma generates types that look somewhat like this:

export const ExampleEnum: {
  FOO: 'foo';
  BAR: 'bar';
};

export type ExampleEnum = (typeof ExampleEnum)[keyof typeof ExampleEnum];

which produces the same error when put into a model:

There was a problem resolving type of 'ExampleEnum'.
There was a problem resolving type of 'ExampleModel'.
Generate routes error.
 Error: Unknown type: IndexedAccessType
At: /my/project/root/xxx/enum.d.ts:6:6.
This was caused by 'export type ExampleEnum = typeof ExampleEnum[keyof typeof ExampleEnum];'
    at new GenerateMetadataError (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/exceptions.js:22:28)
    at TypeResolver.resolve (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:339:19)
    at TypeResolver.getTypeAliasReference (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:581:353)
    at TypeResolver.getReferenceType (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:556:38)
    at TypeResolver.resolve (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:372:34)
    at TypeResolver.propertyFromSignature (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:799:143)
    at /my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:765:161
    at Array.map (<anonymous>)
    at TypeResolver.getModelProperties (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:765:124)
    at TypeResolver.getModelReference (/my/project/root/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:605:31)

I can confirm that the possible solution provided by @m-doi2 gets rid of the error and seems to produce correct routes and specs for the simple example above.

It would be great if this issue could be reopened and reevaluated.

Thank you!

1reaction
ngaercommented, Nov 3, 2021

I’m having the same issues on the latest version (v.3.14.1) as well. I also use Prisma which generates enum types like described above:

export const MessageState: {
  pending: 'pending',
  available: 'available'
};

export type MessageState = (typeof MessageState)[keyof typeof MessageState]

And it gives me the same Error: Unknown type: IndexedAccessType error.

I tested it using #799 version and it also produces the same errors.

And I could also confirm what the fix suggested by @m-doi2:

// ↓added
if (ts.isIndexedAccessTypeNode(this.typeNode)) {
  return new TypeResolver(this.typeNode.indexType, this.current, this.typeNode, this.context, this.referencer).resolve();
}
// ↑added

if (ts.isParenthesizedTypeNode(this.typeNode)) {
...

resolves the issues and produces correct types. And all tests are passed, so it doesn’t seems to break anything.

I can create a PR with suggested fix. @WoH can you please take a look if this is a correct solution?

Read more comments on GitHub >

github_iconTop Results From Across the Web

TSOA Express App return cannot get endpoints - Stack Overflow
I am building a REST API in node.js and Typescript I am using tsoa and swagger for documentation. The build is successful and...
Read more >
Master the TypeScript Keyof Type Operator | by Bytefer
This information tells us that the parameters obj and key implicitly have “any” type. To solve this problem, we can explicitly define the...
Read more >
src/compiler/checker.ts - GitHub
skippedOn = key; return diagnostic; } function error(location: Node ... the exports of another symbol (meaning we have a route to qualify it...
Read more >
Documentation - Conditional Types - TypeScript
Create types which act like if statements in the type system. ... In this example, TypeScript errors because T isn't known to have...
Read more >
tsoa - npm
Specify error response types for Swagger; Authentication; Path mapping ... generate swagger.json tsoa swagger // generate routes tsoa routes.
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