tsoa icon indicating copy to clipboard operation
tsoa copied to clipboard

GenerateMetadataError: Unknown type: IndexedAccessType

Open douglasg14b opened this issue 1 year ago • 12 comments

Sorting

  • I'm submitting a ...

    • [x] bug report
    • [ ] feature request
    • [ ] support request
  • I confirm that I

    • [x] used the search to make sure that a similar issue hasn't already been submit

I found several referneced, but they all appeard to be fixed...?

Expected Behavior

When I tun tsoa routes the following controller fails:

export type BaseIVR3Config = {
    walkingSkeletonPath: WalkingSkeletonPath;
    bestMovies: BestMovies;
};

export type BaseIVR3ConfigKey = keyof BaseIVR3Config;
export type BaseIVR3ConfigValue = BaseIVR3Config[BaseIVR3ConfigKey]; // WalkingSkeletonPath | BestMovies

type WalkingSkeletonPath = 'A' | 'B';
type BestMovies = {
    title: string;
    year: number;
}[];

@Route('config2')
export class Config2Controller extends Controller {
    constructor(private useCases: ConfigUseCases) {
        super();
    }

    @Get('{key}')
    async getByKey(@Path() key: BaseIVR3ConfigKey): Promise<BaseIVR3ConfigValue | 'error'> {
        const result = await this.useCases.getByKey(key);

        if (result.ok) {
            return result.value.value;
        }

        return 'error';
    }
}

Current Behavior

This fails with:

Generate routes error. GenerateMetadataError: Unknown type: IndexedAccessType This was caused by 'BaseIVR3Config[BaseIVR3ConfigKey] | 'error''

Possible Solution

Unknown

Steps to Reproduce

Use the above code with tsoa

Context (Environment)

Version of the library: 6.2.1 Version of NodeJS: 18.13.0

  • Confirm you were using yarn not npm: [ ]
    • We are using pnpm

Detailed Description

N/A See above

Breaking change?

douglasg14b avatar May 03 '24 22:05 douglasg14b

Hello there douglasg14b 👋

Thank you for opening your very first issue in this project.

We will try to get back to you as soon as we can.👀

github-actions[bot] avatar May 03 '24 22:05 github-actions[bot]

Oh, found another, is this the same problem? I see other issues like this that appear to be solved 🤔

Indexed types like this make up a majority of any typings we have when it comes to configuration or definitions. It's almost impossible to avoid index types through the entire type tree as they are a fundamental part of most TS usage.

Is there any particular reason that: type Response = WalkingSkeletonPath | BestMovies is fine but type Response = BaseIVR3Config[BaseIVR3ConfigKey] does not even though they are both union types?

https://github.com/lukeautry/tsoa/issues/1375

douglasg14b avatar May 03 '24 22:05 douglasg14b

Hm, this is actually causing a lot of pain at multiple layers, I wonder how to work around it.

douglasg14b avatar May 07 '24 22:05 douglasg14b

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Jun 07 '24 00:06 github-actions[bot]

Bad bot.

How to speedrun fragmented information & hidden problems 101.

douglasg14b avatar Jun 07 '24 01:06 douglasg14b

Would you like to submit a PR to fix this issue?

WoH avatar Jun 07 '24 09:06 WoH

@WoH I actually went through and tried to understand how this works, and honestly submitting a PR for this is quite the task since I have no context on the codebase, and there isn't much in the way of guidance on the decisions that have been made, or how to navigate them. There's cruft, but not much that explains it, where to look, how things are put together, why various "things" are the way they are, resources...etc

I'm guessing that's a 10-40h task, or even longer. Someone who is already familiar with how TSOA is put together, and has this context may be able to do this in just a few hours.

At the very minimum, someone knowledgeable should provide design guidance, learning resources, and other information to get someone started on this problem.

douglasg14b avatar Jun 21 '24 21:06 douglasg14b

Sure, I can give you some guidance:

The first step is to debug this construction by both the Parser, as well as the information the type checker provides.

These are the 2 possible sources, TS has some information on both of these here:

https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API

To quickly visualize the AST, this is a great tool:

https://ts-ast-viewer.com/#

IIRC there's a TS discord channel where you can probably also ask for help w/r/t making sense of the Type you want to convert.

Then, tsoa is actually pretty simple, once you understand the idea.

We go though all the class declarations with a Controller Annotation and work through them. Controller -> Method -> Collect inputs, collect outputs. The TypeResolver does TS Type -> generic OpenAPI type (Metadata) From this metadata, we generate

  • the OAS version specific type (SpecGenerator 2/3)
  • the router with validation (by handing it over to the templating)

E: In your case, take a look around here: https://github.com/lukeautry/tsoa/blob/master/packages/cli/src/metadataGeneration/typeResolver.ts#L454

WoH avatar Jun 24 '24 09:06 WoH

@WoH Dumb question, but what's the workflow for debugging TSOA at runtime (Breakpoints & step through). Is primarily through tests, or can I ad-hoc attach a debugger to it while building our own API definitions?

I've been reading through the linked code, and stepping a debugger through it will probably be a lot more helpful 🤔

douglasg14b avatar Sep 07 '24 00:09 douglasg14b

@WoH Dumb question, but what's the workflow for debugging TSOA at runtime (Breakpoints & step through). Is primarily through tests, or can I ad-hoc attach a debugger to it while building our own API definitions?

I've been reading through the linked code, and stepping a debugger through it will probably be a lot more helpful 🤔

I'll usually debug from the test suite, but you should be able to debug your app. But make sure node_modules are not ignored in the debugger config.

If you're using vscode, you can get it to generate a debug config that you'll wanna point to node_modules/.bin/tsoa and call it with routes or spec as an arg.

WoH avatar Sep 07 '24 08:09 WoH

Hi,

Has someone found a solution for this issue? I'm also suffering it. I'm trying to use Prisma-generated types along with tsoa; they don't play well together.

This is this type I need to use as a response:

type result = Prisma.userGetPayload<{
        include: {
          country: { select: { id: true, name: true; }; };
        };
      }>;

This is the error:

There was a problem resolving type of 'API.RoleDistrib.Results.get'.
typeResolver.js:755
Generate swagger error.
 Error: Unknown type: IndexedAccessType
At: [...]
This was caused by 'declare type GetResult_2<P extends Payload, A, O extends Operation = 'findUniqueOrThrow', Null = null> = {
    findUnique: GetFindResult<P, A> | Null;
    findUniqueOrThrow: GetFindResult<P, A>;
    findFirst: GetFindResult<P, A> | Null;
    findFirstOrThrow: GetFindResult<P, A>;
    findMany: GetFindResult<P, A>[];
    create: GetFindResult<P, A>;
    createMany: GetBatchResult;
    update: GetFindResult<P, A>;
    updateMany: GetBatchResult;
    upsert: GetFindResult<P, A>;
    delete: GetFindResult<P, A>;
    deleteMany: GetBatchResult;
    aggregate: GetAggregateResult<P, A>;
    count: GetCountResult<A>;
    groupBy: GetGroupByResult<P, A>;
    $queryRaw: unknown;
    $executeRaw: number;
    $queryRawUnsafe: unknown;
    $executeRawUnsafe: number;
    $runCommandRaw: JsonObject;
    findRaw: JsonObject;
    aggregateRaw: JsonObject;
}[O];'
    at TypeResolver.resolveIndexedAccessTypeNode ([...]/node_modules/.pnpm/@[email protected]/node_modules/@tsoa/cli/dist/metadataGeneration/typeResolver.js:435:15)
    at TypeResolver.resolve

I'm sorry I can't dive into the tsoa library and try to make a fix, this is way above my knowledge

pmullot avatar Oct 02 '24 11:10 pmullot

I think the "Unknown type: IndexedAccessType" error can occur in several cases that are not handled in the function TypeResolver.resolveIndexedAccessType

BartaG512 avatar Jan 17 '25 11:01 BartaG512