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

Nested interfaces ignored when declared in other files (Typescript -> OpenAPI) #37

Open
TheDechev opened this issue Aug 24, 2023 · 5 comments

Comments

@TheDechev
Copy link

Hey,

When using NodeJS/ES6 to convert existing Typescript interfaces to OpenAPI it ignores nested interfaces that are declared in other files.

For example, the following interface:

// main.ts
export interface MyResponse {
  id: string;
  status: StatusResponse;
}

Uses the StatusResponse that is defined in another file as simply:

//helper.ts
export interface StatusResponse {
  status: string;
  errorMessages?: string[];
}

Yet the final MyResponse schema ignores the status field entirely and just shows the id field.

Has anyone encountered this before or can suggest a solultion?

Thanks

@TheDechev
Copy link
Author

ping

@anantanandgupta
Copy link

//base.type.ts
export type BaseType = {
  readonly _id?: string;
};

//address.type.ts
export type Address = BaseType & {
  addressLine1: string;
  addressLine2?: string;
  city: string;
  countryCode: string;
  postalCode?: string;
  state?: string;
  readonly country?: Country;
}

//country.type.ts
export type Currency = {
  code: string;
  name: string;
  symbol?: string;
}

export type PostalCode = {
  format?: string;
  regex?: string;
}

export type Country = BaseType & {
  currencies: Array<Currency>;
  flagImage: string;
  isEnabled: boolean;
  iso2: string;
  iso3: string;
  name: string;
  officialName?: string;
  postalCode: PostalCode;
  timezones: Array<string>;
}

gets converted into below files

//base.type.yaml
... removed some parts of yamls here for reducing the size ...
components:
  schemas:
    BaseType:
      properties:
        _id:
          title: BaseType._id
          type: string
      additionalProperties: false
      title: BaseType
      type: object

//address.type.yaml
... removed some parts of yamls here for reducing the size ...
components:
  schemas:
    Address:
      properties:
        addressLine1:
          title: addressLine1
          type: string
        addressLine2:
          title: addressLine2
          type: string
        city:
          title: city
          type: string
        countryCode:
          title: countryCode
          type: string
        postalCode:
          title: postalCode
          type: string
        state:
          title: state
          type: string
        country:
          title: country
      required:
        - addressLine1
        - city
        - countryCode
      additionalProperties: false
      title: Address
      type: object

//country.type.yaml
... removed some parts of yamls here for reducing the size ...
components:
  schemas:
    Currency:
      properties:
        code:
          title: Currency.code
          type: string
        name:
          title: Currency.name
          type: string
        symbol:
          title: Currency.symbol
          type: string
      required:
        - code
        - name
      additionalProperties: false
      title: Currency
      type: object
    PostalCode:
      properties:
        format:
          title: PostalCode.format
          type: string
        regex:
          title: PostalCode.regex
          type: string
      additionalProperties: false
      title: PostalCode
      type: object
    Country:
      properties:
        currencies:
          items:
            $ref: '#/components/schemas/Currency'
          title: currencies
          type: array
        flagImage:
          title: flagImage
          type: string
        isEnabled:
          title: isEnabled
          type: boolean
        iso2:
          title: iso2
          type: string
        iso3:
          title: iso3
          type: string
        name:
          title: name
          type: string
        officialName:
          title: officialName
          type: string
        postalCode:
          $ref: '#/components/schemas/PostalCode'
          title: postalCode
        timezones:
          items:
            type: string
          title: timezones
          type: array
      required:
        - currencies
        - flagImage
        - isEnabled
        - iso2
        - iso3
        - name
        - postalCode
        - timezones
      additionalProperties: false
      title: Country
      type: object

this is not a valid yaml and doesn't represent the real type schema.

@pocketcolin
Copy link

Anyone figure out a solution to this issue?

@sergeyshmakov
Copy link

sergeyshmakov commented Oct 30, 2024

If it would help for someone here is some tips:

  • Better to use interfaces to describe the API of your package
  • Better to isolate your public API types (i.e. not contain references in these files to some business logic and describe pure interfaces)
  • Use dts-bundle-generator to boundle all your public API types into single file and then use typeconv to convert this .d.ts file to what ever you want.

@myorkgitis-rtg
Copy link

Has anyone had any luck converting TS types with a reference to a type exported from a dependency? i.e. converting the following so that the properties of User and any of its nested types are included in the output OpenAPI type for TMyUser?

// my-types.ts
import { User } from '@microsoft/microsoft-graph-types'

declare namespace MyTypes {
  export interface TMyUser extends User {
   customField: string
  };
}

When I try converting the above, I get:

paths: {}
components:
  schemas:
    MyTypes.TMyUser:
      properties:
        customField:
          title: MyTypes.TMyUser.customField
          type: string
      required:
        - customField
      additionalProperties: false
      title: MyTypes.TMyUser
      type: object

Which does not include any of the properties from the imported type User.

This is the tsconfig.json file I'm using. Not sure if I need to set it up differently to include the types referenced from @microsoft/microsoft-graph-types.

{
  "compilerOptions": {
    "module": "ESNext",
    "esModuleInterop": true,
    "target": "ESNext",
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "build",
    "jsx": "react",
    "resolveJsonModule": true,
    "types": [
      "node",
      "jest"
    ],
    "paths": {
      "@types/*": ["node_modules/@types/*"],
      "@microsoft/*": [
        "node_modules/@microsoft/*"
      ]
    }
  },
  "lib": ["ES2021"],
  "include": ["src/**/*.ts", "src/api/database/models/initialized/my-types.ts"]
}

I'm not sure if the omitted properties from User is a bug, an intentional limitation of typeconv, or an error on my part due to my tsconfig.json and/or how I'm importing/exporting the dependency's type.

Any help is much appreciated!

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

5 participants