tsoa icon indicating copy to clipboard operation
tsoa copied to clipboard

[Recursive types] TypeError: Cannot read property 'forEach' of undefined

Open dasdachs opened this issue 3 years ago • 6 comments

When using a return type that is defined as a recursive type the typeresolver can not generate the metadata and throws TypeError: Cannot read property 'forEach' of undefined.

Sorting

  • I'm submitting a .

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

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

Expected Behavior

TSOA should handle recursive types or at least provide an option to define the max depth of the interface resolution.

Current Behavior

Currently even simple recursive interfaces get result in an error.

Possible Solution

Handle recursive types or at least provide a option to stop at a depth level.

Steps to Reproduce

Note: this is obviously a contrived example and I have a real world example with nested templates where the recursive definition is more than valid as a template can have embedded templates that again have embedded templates etc. And to make things more interesting, the templates themselves are complex interfaces with UI and data definitions.

Add this to the tests

// tests/fixtures/testModel.ts
export interface RecursiveTestModel extends BaseModel {
  name: string;
}

interface BaseModel {
  /**
   * @isLong Custom Required long number.
   */
  id: number;
  items?: Item[];
}

interface Item extends BaseModel {
  name: string;
}
// tests/fixtures/controllers/typeInferenceController.ts
@Get('recursiveTypeResponse')
public recursiveTypeResponse(): RecursiveTestModel {
  return new ModelService().getRecursiveTestModel();
}
// tests/fixtures/services/modelService.ts
public getRecursiveTestModel(): RecursiveTestModel {
    return {
      id: 1,
      name: 'Parent object',
      items: [
        {
          id: 2,
          name: 'Child 1',
        },
        {
          id: 3,
          name: 'Child 2',
          items: [
            {
              id: 4,
              name: 'SubChild 1',
            },
          ],
        },
      ],
    };
  }

Context (MacOS Big Sur 11.6)

Version of the library: 3.14.0 Version of NodeJS: 16.13.0

  • [x] Confirm you were using yarn not npm

Detailed Description

I have no idea where to start, but I am more than willing to spend some time on it provided with guidance where to start working.

Breaking change?

Hard to analyse but shoudl be none as existing project would still work (no recursive types) and new project could leverage this.

dasdachs avatar Nov 04 '21 15:11 dasdachs

Hello there dasdachs 👋

Welcome to tsoa !!💖🥳

Thank you and congratulations 🎉 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 Nov 04 '21 15:11 github-actions[bot]

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 Dec 05 '21 00:12 github-actions[bot]

Any news about this? Can I help?

dasdachs avatar Dec 09 '21 04:12 dasdachs

I can confirm we are experiencing the same with models that are somewhat recursive. It happens both with v3.14.0 and 4.0.0-rc.0

celayale avatar Feb 25 '22 07:02 celayale

Any news?

korytoff avatar Dec 12 '22 22:12 korytoff

I'm seeing this issue happen as well in the latest 5.x version

The actual error (as well as an output of the referenced object) in case anyone is searching for the specific error

> [email protected] build
> tsoa spec-and-routes && tsc

{
  dataType: 'refObject',
  refName: 'Maybe<ExampleBranch>',
  description: undefined,
  properties: undefined
}
Generate routes error.
 TypeError: Cannot read properties of undefined (reading 'filter')
    at /home/rridley/projects/tsoa-project-test/node_modules/@tsoa/cli/dist/swagger/specGenerator3.js:138:59
    at Array.map (<anonymous>)
    at SpecGenerator3.buildSchema (/home/rridley/projects/tsoa-project-test/node_modules/@tsoa/cli/dist/swagger/specGenerator3.js:134:53)
    at SpecGenerator3.buildComponents (/home/rridley/projects/tsoa-project-test/node_modules/@tsoa/cli/dist/swagger/specGenerator3.js:72:27)
    at SpecGenerator3.GetSpec (/home/rridley/projects/tsoa-project-test/node_modules/@tsoa/cli/dist/swagger/specGenerator3.js:26:30)
    at generateSpec (/home/rridley/projects/tsoa-project-test/node_modules/@tsoa/cli/dist/module/generate-spec.js:25:77)
    at generateSpecAndRoutes (/home/rridley/projects/tsoa-project-test/node_modules/@tsoa/cli/dist/cli.js:290:156)

I've also included a full sample project here https://github.com/keslerm/tsoa-issue-example

To add just one more bit of useful information:

In my example I created a controller method that returned the nested type that was failing directly. Once I did this, everything built and ran as expected.

Removing that controller method resulted in it not building again.

keslerm avatar Sep 28 '23 20:09 keslerm