Open
Description
What happened?
Typescript 4.7.4
Minimal reproducible code:
const octokit = new Octokit()
const response = await octokit.request(
'GET /repos/{owner}/{repo}', {
owner: '',
repo: '',
})
if (response.status === 404) { // <= Typescript error: TS2367: This condition will always return 'false' since the types '200' and '404' have no overlap.
throw new Error('Repo not found')
}
What did you expect to happen?
@octokit/openapi-types
already defines different responses codes including 404:
/** The `parent` and `source` objects are present when the repository is a fork. `parent` is the repository this repository was forked from, `source` is the ultimate source for the network. */
"repos/get": {
parameters: {
path: {
/** The account owner of the repository. The name is not case sensitive. */
owner: components["parameters"]["owner"];
/** The name of the repository. The name is not case sensitive. */
repo: components["parameters"]["repo"];
};
};
responses: {
/** Response */
200: {
content: {
"application/json": components["schemas"]["full-repository"];
};
};
301: components["responses"]["moved_permanently"];
403: components["responses"]["forbidden"];
404: components["responses"]["not_found"];
};
};
So I expect response.status
type should be 200 | 301 | 403 | 404
What the problem might be
Maybe because Endpoints.ExtractOctokitResponse doesn't handle error response codes?
declare type SuccessStatuses = 200 | 201 | 202 | 204;
declare type RedirectStatuses = 301 | 302;
declare type EmptyResponseStatuses = 201 | 204;
declare type KnownJsonResponseTypes = "application/json" | "application/scim+json" | "text/html";
declare type SuccessResponseDataType<Responses> = {
[K in SuccessStatuses & keyof Responses]: GetContentKeyIfPresent<Responses[K]> extends never ? never : OctokitResponse<GetContentKeyIfPresent<Responses[K]>, K>;
}[SuccessStatuses & keyof Responses];
declare type RedirectResponseDataType<Responses> = {
[K in RedirectStatuses & keyof Responses]: OctokitResponse<unknown, K>;
}[RedirectStatuses & keyof Responses];
declare type EmptyResponseDataType<Responses> = {
[K in EmptyResponseStatuses & keyof Responses]: OctokitResponse<never, K>;
}[EmptyResponseStatuses & keyof Responses];
declare type GetContentKeyIfPresent<T> = "content" extends keyof T ? DataType<T["content"]> : DataType<T>;
declare type DataType<T> = {
[K in KnownJsonResponseTypes & keyof T]: T[K];
}[KnownJsonResponseTypes & keyof T];
declare type ExtractOctokitResponse<R> = "responses" extends keyof R ? SuccessResponseDataType<R["responses"]> extends never ? RedirectResponseDataType<R["responses"]> extends never ? EmptyResponseDataType<R["responses"]> : RedirectResponseDataType<R["responses"]> : SuccessResponseDataType<R["responses"]> : unknown;