Skip to content

Suggestion: improve readability of data type #2022

Open
@OliverJAsh

Description

@OliverJAsh

Description

When inspecting data returned by openapi-fetch, the type can be quite difficult to read, and the appearance seems to vary. For example:

index.ts:

import createClient from "openapi-fetch";
import type { paths } from "./schema";

const client = createClient<paths>({ baseUrl: "https://myapi.dev/v1/" });

const x = await client.GET("/photos/random", {
  params: { query: { count: 10 } },
});
x.data;
/*
SuccessResponse<{
    200: {
        headers: {
            [name: string]: unknown;
        };
        content: {
            "application/json": components["schemas"]["Photo"] | components["schemas"]["Photo"][];
        };
    };
}, `${string}/${string}`> | undefined
*/

const y = await client.GET("/photos", {});
y.data;
/*
{
    updated_at: string;
    id: string;
}[] | undefined
 */

Reproduction

In case it helps for testing, here's the schema JSON I used.

Expected result

In both of these examples I think it would be better if the data simply appeared as Photo, as per the component name in the schema.

I believe this would be possible if openapi-typescript generated individual interfaces for each component, rather than one interface with components as nested objects. When TypeScript prints the type e.g. inside hover tooltips and error messages, TypeScript will preserve the name of interfaces rather than inlining their contents.

Furthermore, this change is required to force TypeScript to compute the type in the first example:

+type Prettify<T> = { [K in keyof T]: T[K]; } & {};
 
 export type FetchResponse<T extends Record<string | number, any>, Options, Media extends MediaType> =
   | {
-      data: ParseAsResponse<SuccessResponse<ResponseObjectMap<T>, Media>, Options>;
+      data: Prettify<ParseAsResponse<SuccessResponse<ResponseObjectMap<T>, Media>, Options>>;

With I tested both of those changes, this is what I was able to achieve:

const x = await client.GET("/photos/random", {
  params: { query: { count: 10 } },
});
x.data;
/*
Photo[] | {
    id: string;
} | undefined
*/

const y = await client.GET("/photos", {});
y.data;
/*
Photo[] | undefined
 */

(I still need to figure out why Photo is still being inlined in the first example.)

Checklist

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestopenapi-fetchRelevant to the openapi-fetch library

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions