tsoa
tsoa copied to clipboard
Multiple matching models error only on version 3.1.0 and later
Sorting
-
I'm submitting a ...
- [v] bug report
- [ ] feature request
- [ ] support request
-
I confirm that I
- [v] used the search to make sure that a similar issue hasn't already been submit
Expected Behavior
I upgraded tsoa from 3.0.8 lately, and i'm getting Error: Multiple matching models found for referenced type LoDashStatic; please make model names unique.
All i did was include the 'Lodash' library and use it in the project. Everything works perfectly on 3.0.8 but on 3.1.0 and later (3.2.1 tested) it doesn't work anymore.
@endor could this be related to #692?
Lodash
exports LoDashStatic
within a namespace, so it's definitely possible that tsoa
now finds that type, where before it couldn't. I'm not really sure why it would throw that error though, unless you're using Lodash
types within your models. This needs some further debugging, which would be easier if you could tell us if and how you're including Lodash
s types in your models. I could try to look into this soonish.
We're having the same problem with the @kubernetes/client-node
package. We tried using the ignore
config so Tsoa wouldn't crawl the node_modules
folder, but it doesn't seem to respect that config setting at all.
ok... checking back in with an update. We had complexity because we're running a monorepo that I won't get into here, but this setting in tsconfig.json
worked to get tsoa to ignore the duplicate definition in kubernetes:
"ignore": ["**/node_modules/@kubernetes/**"],
@WoH I don't yet understand, why this is a bug. It's discovering duplicate definitions, that it didn't discover before. How is this supposed to be fixed? We already have documentation telling users what to do in case of duplicate definitions.
The issue I'm seeing is that it's very much unlikely that LodashStatic is exposed for tsoa to use in the API definition. That's an assumption, until I know I shouldn't have classified this as a bug.
It shouldn't be discovering anything in node_modules
, should it? I can say for sure in our case that we don't want anything in node_modules
exposed.
Disagree. If you expose some interface from some library as a body parameter you are using that'll be in node_modules. If you use any of the TS utility types to define the response type of your controller method, guess where that's coming from? However, where I will agree is that, unless this interface has to be used to describe your API, it should not "leak". That's why I initially already labeled this a bug.
E; If you want to never expose something from node_modules, that's ok, but I'd consider it a bad default to apply. As you can remove them using tsconfig, that's kinda fine from imho.
Yes, I agree that if we expose it via an interface, it should be included, but that's not the case here. One of my developers had this happen with the @kubernetes
library on his branch. I installed that library on my own branch (with no Kubernetes functionality in my branch). All I had to do to trigger the error was to import the module from @kubernetes
in one of my controller files. I never actually used it.
I don't yet understand, why this is a bug
All I had to do to trigger the error was to import the module from @kubernetes in one of my controller files. I never actually used it.
That's not what should be happening. Thanks for confirming my suspicion. This seems to be a bug.
I've tried to investigate this a bit. I couldn't reproduce it with @kubernetes/client-node
, but I could reproduce it with lodash
. I haven't yet figured out what the actual problem is, but it seems that Partial
, which we use in our TestModel
has a member called ___
, and LoDashStatic
seems to be a type alias for that. I hope to understand this a little better soon.
I can share a similar experience. We have a Status
interface, that, starting with the namespace patch, instead renders a Status
enum from the Sentry node_modules lib.
This is the reason for the concerns I mentioned when I suggested using TS to "jump to declaration" instead of using names, which may not be unique, especially after introducing namespaces declarations into the list of candidates.
Maybe we can at least fix the check for unique declarations if multiple declarations exist (which seems to not be happening properly when a namespaced and a non-namespaced declaration of the same name exist.
We can try. Otherwise we can also revert the change.
In my case, if we throw an error and ask for @tsoaModel
, that's perfect.
I think that would be a nice and easy solution, but I guess in case of lodash
, it doesn't really work, because there's not really a name overlapping in the models we've defined. That's why we also cannot choose the "correct" model, if we have multiple. Like say we would generally choose the one outside of a namespace or such. lodash
might be a special case, but I guess it's common enough that it should be fixed somehow.
It is probably better to use TS' "jump to declaration", though I'm not aware how that works and more importantly, I probably won't have the time in the very near future to do this properly. If you could let me know some resource explaining this in more detail, I might get to it at some point.
As you say, we have a block that filters the models, should there be multiple matches. What it currently does is:
- check for models from TS and remove those
- check for models marked
@tsoaModel
and prefer those
We could add another "rule" here to prefer "local" models to ones found in node_modules
, but in the case of lodash
it means that there are no models left after the filtering and it just doesn't resolve Partial
correctly.
It's probably good to understand why it jumps from Partial
to lodash
to solve this. Might get to this soonish.
Okay, finally I have at least found the issue, and it makes somewhat more sense. lodash
is having an interface called Partial
defined in their namespace, so we have two competing definitions of Partial
. One in lodash
and one in TS
. But as I said above, we filter the types defined in TS for model type declarations, so it uses the lodash
one. I am not sure how that worked before introducing the namespace change, as that should have resulted in not finding anything. I guess I'll go back in git and look it up. Anyway, I wish we had better documentation, so I'd know why we filter the TS types out. But I guess it's also a more general problem, if we use two libraries defining the same thing, which we use in one of our models, there's no easy way to mark that as @tsoaModel
. Or am I missing something?
I have similar issue. One of classes has name "Stats" and it conflicts with Stats from @types/node/fs.d.ts
Full error stack:
Generate swagger error.
Error: Multiple matching models found for referenced type Stats; please make model names unique. Conflicts found: "/home/aaleksandrov/work/stream-ingester/node_modules/sdk/src/model/SurveyResponse.ts"; "/home/aaleksandrov/work/stream-ingester/node_modules/@types/node/fs.d.ts".
in 'SurveyResponseController.submitSurveyResponseMessage'
Worked this around by adding
"ignore": ["**/node_modules/@types/node/**"],
@aaleksandrov this is the expected behavior we want here (assuming you use a Stats type/interface in one of your controllers).
@WoH I don't use Stats
from @types/node/fs.d.ts
Hit the same issue trying to upgrade from 3.0.8: Error: Multiple matching models found for referenced type LoDashStatic
Workaround: add this to tsoa.json
:
"ignore": ["**/node_modules/@types/lodash/**"],
I've been getting this error
Error: Multiple matching models found for referenced type LoDashStatic
only when trying to make a partial interface:
export interface UpdateRenderTemplate extends Partial<CreateRenderTemplate> {}
"@tsoa/cli": "^3.8.0",
@aldenquimby your workaround didn't work, for me only rewriting partial did it:
type MyPartial<T> = {
[P in keyof T]?: T[P];
};