Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static imports for $refs #579

Open
codan84 opened this issue Feb 7, 2024 · 4 comments
Open

Static imports for $refs #579

codan84 opened this issue Feb 7, 2024 · 4 comments

Comments

@codan84
Copy link

codan84 commented Feb 7, 2024

Given structure like so:

schema/my-stuff.json :

{
   "id": "Stuff",
   "type": "object",
   "properties": {
      "someProp": {
         "$ref": "schema/enums/awesome-enum.json"
      }
  }
}

schema/enums/awesome.json :

{
  "id": "Awesome",
  "type": "string",
  "enum": [
    "FOO",
    "BAR"
  ],
  "tsEnumNames": [
    "FOO",
    "BAR"
  ]
}

When I run the following cli command:

npx json2ts --no-additionalProperties --no-enableConstEnums -i 'schema/**/*.json' -o packages/model/src/

I will get roughly this:

packages/model/src/awesome.ts :

export enum Awesome {
  FOO = "FOO",
  BAR = "BAR"
}

packages/model/src/my-stuff.ts :

export interface Stuff {
  someProp?: Awesome
}

export enum Awesome {
  FOO = "FOO",
  BAR = "BAR"
}

Awesome enum is now declared twice. And if I then reference this Awesome in any other schemas, it will be re-declared in every single file it is referenced.
Am I missing some way to import these instead? Or alternatively having everything in 1 file...

@codan84
Copy link
Author

codan84 commented Feb 8, 2024

To go around the issue I had to introduce a kind of root-schema to hold all assets.
root.json :

{
  "id": "Root",
  "title": "Root",
  "description": "Root schema for all assets",
  "type": "object",
  "allOf": [
    {
      "$ref": "schema/new-draft.json"
    },
    {
      "$ref": "schema/draft.json"
    },
    (.......)
  ]
}

Each of the ones referenced in the above then references other schemas.
Having this I can run:

npx json2ts --no-additionalProperties --no-enableConstEnums -i 'schema/root.json' -o packages/model/src/generated-types.ts

To get something like:

/**
 * Root schema for all assets
 */
export type Root = NewDraft & Draft & (...);

/**
 * A new draft
 */
export interface NewDraft {
(...)

export interface Draft {
(...)

export interface (...)

I do not like that export of Root, but can't figure out a way to get the desired outcome any other way...

@gino-m
Copy link

gino-m commented Feb 22, 2024

@codan84 Are you also seeing duplicate interface declarations in the resulting output for $refs which appear in multiple places? I was trying to use --no-declareExternallyReferenced, but then individual files generate don't include import statements. :/

@gino-m
Copy link

gino-m commented Feb 22, 2024

As a workaround to generate unique classes, the best I could come up with is merged them into a single file. This has the benefit of not requiring a root schema, and provides unique (non-duplicate) class definitions:

mkdir -p dist/generated && \
  npx json2ts \
    --no-declareExternallyReferenced \
    --no-bannerComment \
    --cwd=src \
    -i 'src/*.schema.json' \
    -o dist/tmp/ && \
  cat dist/tmp/*.schema.d.ts > dist/generated/schema.d.ts

@MattLJoslin
Copy link

MattLJoslin commented Mar 7, 2024

This is definitely a bit of a hack but one work around I found was to do
json2ts --bannerComment "/* eslint-disable */
import * from './base_types.d'"

Then I split the schema generation into 2 steps. One for base types which should not import themselves and another for all my other types. Of course this doesn't really solve the full issue but at least gave me a path around this temporarily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants