openapi-typescript
openapi-typescript copied to clipboard
Schema references show only "raw" type in IDE hints
Description
Generated schema types with references to other types present an awkward IDE experience.
// generated "child type
/**
* BoardDTO
* @description Deserialized board record with cover image URL and image count.
*/
BoardDTO: {
/**
* Board Id
* @description The unique ID of the board.
*/
board_id: string;
/**
* Board Name
* @description The name of the board.
*/
board_name: string;
/**
* Created At
* @description The created timestamp of the board.
*/
created_at: string;
/**
* Updated At
* @description The updated timestamp of the board.
*/
updated_at: string;
/**
* Deleted At
* @description The deleted timestamp of the board.
*/
deleted_at?: string;
/**
* Cover Image Name
* @description The name of the board's cover image.
*/
cover_image_name?: string;
/**
* Image Count
* @description The number of images in the board.
*/
image_count: number;
};
// generated "parent" type
/**
* OffsetPaginatedResults[BoardDTO]
* @description Offset-paginated results
*/
OffsetPaginatedResults_BoardDTO_: {
/**
* Items
* @description Items
*/
items: (components["schemas"]["BoardDTO"])[]; // <----- schema reference to BoardDTO
/**
* Offset
* @description Offset from which to retrieve items
*/
offset: number;
/**
* Limit
* @description Limit of items to get
*/
limit: number;
/**
* Total
* @description Total number of items in result
*/
total: number;
};
// in the app - extract the type
type OffsetPaginatedResults_BoardDTO_ = components['schemas']['OffsetPaginatedResults_BoardDTO_']
// IDE hint (VSCode) for the type - note that `BoardDTO` is fully inferred (?) - same for either side of the equals sign in the above extraction
{
items: {
board_id: string;
board_name: string;
created_at: string;
updated_at: string;
deleted_at?: string | undefined;
cover_image_name?: string | undefined;
image_count: number;
}[];
offset: number;
limit: number;
total: number;
};
// what I want to see in the IDE hint
type OffsetPaginatedResults_BoardDTO_ = {
items: BoardDTO[];
offset: number;
limit: number;
total: number;
};
I believe this is a consequence of making the types be references to properties of another type.
Another awkward developer experience knock-on effect is that type aliases lose the JSDoc data:
Hovering over components['schemas']['OffsetPaginatedResults_ImageDTO_'] (missing JSDoc):
Hovering over the 1-to-1 type alias T (with JSDoc):
Proposal
I'm not sure how to solve this.
Checklist
- [X] I’m willing to open a PR for this (see CONTRIBUTING.md)*
- I'm happy to attempt to open a PR if there is a clear solution that aligns with the project goals
Slightly-relevant, but the very first version of this library actually did try and export PascalCase pretty names for schema objects. It was useful in theory, but in practice, schemas can get so complicated there will always be conflicts (e.g. you can have duplicate parameter names across different endpoints with different types, you can have the same Schema Object name duplicated across remote schemas, you can have invalid JS characters, etc etc). So just accepting your schema “as-written” and lumping everything into one interface has been a good decision, but it results in the problem you described.
While scanning the schema, we do keep track at all times of where we are with a path string that does contain the object name. It would probably be reasonable to pass that in to getSchemaObjectComment() at the very least as the title of the comment (e.g. if the path was #/components/schemas/OffsetPaginatedResults, perhaps the title of the comment should start with that—either the whole path, or just the last name)
If that makes sense, and is a clear direction, I’d love a PR for that!
Also just a note in advance: when it comes to changing function parameters, I usually discourage ordered params, and prefer either myFunction(paramObject) or myFunction(thing, optionsObject). So if modifying getSchemaObjectComment() I think either getSchemaObjectComment(schemaObject, options) or getSchemaObjectComment(paramsObject) would work (I’ve just been burned in the past by unnamed params, both when several positions share types as well as getting into the dreaded territory of trying to make some ordered params optional)
This issue is stale because it has been open for 90 days with no activity. If there is no activity in the next 7 days, the issue will be closed.
This issue was closed because it has been inactive for 7 days since being marked as stale. Please open a new issue if you believe you are encountering a related problem.