ajaishankar / openapi-typescript-fetch

A typed fetch client for openapi-typescript
MIT License
233 stars 54 forks source link

Inaccessible unique symbol error when using `FetchErrorType` #37

Open htunnicliff opened 2 years ago

htunnicliff commented 2 years ago

When I attempt to use FetchErrorType<F>, TypeScript emits the following error:

The inferred type of makeHook[^1] references an inaccessible 'unique symbol' type. A type annotation is necessary. ts(2527)

[^1]: makeHook is the name of the calling function in my code.

I investigated this and discovered that the following const declaration (on line 65) is the cause of the problem.

https://github.com/ajaishankar/openapi-typescript-fetch/blob/2e0d66e8e5c7ef74dd406c810b8b2b61f5f5ae1e/src/types.ts#L64-L72

If I modify that source code to export the type, the error I mentioned disappears with no further modifications needed in my own code:

// private symbol to prevent narrowing on "default" error status
-const never: unique symbol = Symbol()
+export const never: unique symbol = Symbol()

type _OpErrorType<T> = {
  [S in Exclude<keyof T, 200 | 201>]: {
    status: S extends 'default' ? typeof never : S
    data: T[S]
  }
}[Exclude<keyof T, 200 | 201>]

Would it be feasible to add an export to this constant to resolve the "inaccessible unique symbol" error here?

htunnicliff commented 2 years ago

Here is an approximation of my calling code. The relevant part of the function is that it accepts an OpenAPI schema paths type in its generic, then lets the user enter one of the available path keys in order to generate a fetcher for the given path.

import { Fetcher } from "openapi-typescript-fetch";
import type { OpenapiPaths } from "openapi-typescript-fetch/dist/cjs/types";

type Gettable = {
  get: unknown;
};

type OnlyGet<T> = {
  [K in keyof T as T[K] extends Gettable ? K : never]: T[K];
};

export function makeHook<
  Paths extends OpenapiPaths<Paths>, 
  Path extends keyof OnlyGet<Paths>
>(path: Path) {
  // Create fetcher
  const fetcher = Fetcher.for<Paths>();
  fetcher.configure({});

  // Create request
  const request = fetcher.path(path).method("get").create();
  type Data = FetchReturnType<typeof request>;
  type Args = FetchArgType<typeof request>;
  type FetchError = FetchErrorType<typeof request>; // <-- TS2527 error

  // ... do other stuff to create and return a hook 
}