openapi-typescript-fetch icon indicating copy to clipboard operation
openapi-typescript-fetch copied to clipboard

Inaccessible unique symbol error when using `FetchErrorType`

Open htunnicliff opened this issue 3 years ago • 1 comments

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 avatar Jun 05 '22 17:06 htunnicliff

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 
}

htunnicliff avatar Jun 05 '22 17:06 htunnicliff