You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here, this operation references components['schemas']['content-file'], which is correct, but 'content-file' is an inline object on components['schemas']:
(note: I’ve only shown some properties for brevity)
** Why is this a problem **
We are working in a composite TypeScript monorepo with declarationEmit. That means each package in he monorepo will create a .d.ts file of its exported content for other packages to consume (instead of consuming the source code directly). This greatly speeds-up type performance in large monorepos.
The problem is that, because types are inlined here, whenever we use a function that returns something from our contracts (e.g. with openapi-fetch), the inferred type is also inlined.
This can create huge declaration files, and we’ve already hit the limit, where TypeScript errors out with:
TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.
Some of our endpoint responses are inlined multiple times in the emitted declaration, which is the main cause of reaching the maximum length.
Potential solution
TypeScript will correctly keep import references when packages have their own exported types or interfaces. I was hoping that the --root-types config option would achieve exactly that, but it does not. All it does is create an extra, internally unused type that is in itself, a reference:
export type SchemaContentFile = components['schemas']['content-file'];
Proposal
I think a good solution would be to change how --root-types works, in a way that it doesn’t just reference components['schemas'], but that it becomes the definition for it. In the above example, if we have:
export type SchemaContentFile = {
type: 'file'
encoding: string
size: number
name: string
};
and then use this internally for components['schemas']['content-file']:
I think it would work the same as before for external consumers of SchemaContentFile, but it would allow openapi-fetch to infer the response of a get request towards repos/get-readme to be inferred as a reference to SchemaContentFile rather than an inline type.
Note that operations doesn’t need to change at all - it can still just refer to components['schemas']['content-file'], because that would then be a reference to SchemaContentFile.
Note: It doesn’t matter if those are exported as interface or type - TypeScript will keep importing the root type in both ways.
Checklist
We are currently in the process of trying out to change --root-types in the proposed direction for us. If you agree on that improvement, we’ll gladly commit it upstream.
Sorry; commented confused how it differed from --root-types but you did explain that.
This is something we won’t consider. If you read back through issues going 5+ years, you’d find that exporting top-level types are a minefield of drawbacks, and it limits what OpenAPI can generate. Going further in this direction is a path we‘ve already gone down long ago, and we won’t revisit because at a certain point it breaks because it’s too abstracted from your original schema, myriad things have to be renamed to prevent conflict (not to mention special characters removed). Many people agree with you that the ergonomics are better! No question! But for more advanced usecases this limits how your schema can be named & composed, and this project will always err on the side of “support everyone, even really weird schemas” rather than have opinions. There are lots of opinionated libraries that are good solutions for people.
Description
Right now,
openapi-typescript
returns inlined objects forcomponents
. For example, thegithub
api has an operation for getting the readme:(note: I’ve left out
parameters
for brevity)Here, this
operation
referencescomponents['schemas']['content-file']
, which is correct, but'content-file'
is an inline object oncomponents['schemas']
:(note: I’ve only shown some properties for brevity)
** Why is this a problem **
We are working in a composite TypeScript monorepo with
declarationEmit
. That means each package in he monorepo will create a.d.ts
file of its exported content for other packages to consume (instead of consuming the source code directly). This greatly speeds-up type performance in large monorepos.The problem is that, because types are inlined here, whenever we use a function that returns something from our contracts (e.g. with
openapi-fetch
), the inferred type is also inlined.This can create huge declaration files, and we’ve already hit the limit, where TypeScript errors out with:
Some of our endpoint responses are inlined multiple times in the emitted declaration, which is the main cause of reaching the maximum length.
Potential solution
TypeScript will correctly keep import references when packages have their own exported types or interfaces. I was hoping that the
--root-types
config option would achieve exactly that, but it does not. All it does is create an extra, internally unused type that is in itself, a reference:Proposal
I think a good solution would be to change how
--root-types
works, in a way that it doesn’t just referencecomponents['schemas']
, but that it becomes the definition for it. In the above example, if we have:and then use this internally for
components['schemas']['content-file']
:I think it would work the same as before for external consumers of
SchemaContentFile
, but it would allowopenapi-fetch
to infer the response of a get request towardsrepos/get-readme
to be inferred as a reference toSchemaContentFile
rather than an inline type.Note that
operations
doesn’t need to change at all - it can still just refer tocomponents['schemas']['content-file']
, because that would then be a reference toSchemaContentFile
.Note: It doesn’t matter if those are exported as
interface
ortype
- TypeScript will keep importing the root type in both ways.Checklist
We are currently in the process of trying out to change
--root-types
in the proposed direction for us. If you agree on that improvement, we’ll gladly commit it upstream.The text was updated successfully, but these errors were encountered: