Skip to content

Commit

Permalink
fix(typescript): infer octokit types from the version option pass…
Browse files Browse the repository at this point in the history
…ed to the `Octokit` constructor (#10)
  • Loading branch information
gr2m authored Aug 9, 2021
1 parent f376a96 commit 8f6de6c
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 47 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
"types": "./index.d.ts",
"exports": "./index.js",
"scripts": {
"test": "npm run test:code && npm run test:dts && npm run test:coverage",
"test": "npm run test:code && npm run test:dts && npm run test:ts && npm run test:coverage",
"test:code": "c8 node test.js",
"test:coverage": "c8 check-coverage",
"test:dts": "for d in tests/js/* ; do tsd $d; done",
"test:ts": "for d in tests/ts/*/tsconfig.json ; do echo $d; tsc -p $d; done"
"test:dts": "for d in tests/js/* ; do echo $d; tsd $d; if [ $? -eq 0 ]; then echo ok; else exit 1; fi; done",
"test:ts": "for d in tests/ts/*/tsconfig.json ; do echo $d; tsc -p $d; if [ $? -eq 0 ]; then echo ok; else exit 1; fi; done"
},
"renovate": {
"extends": [
Expand Down
15 changes: 5 additions & 10 deletions packages/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import { RequestInterface } from "./request";
* Global Octokit interfaces that can be extended as needed.
*/
export namespace Octokit {
interface Options<TVersion extends keyof Octokit.ApiVersions = "github.com"> {
/**
* GitHub API Version. Defaults to "github.com"
*/
version?: TVersion;

interface Options {
/**
* GitHub's REST API base URL. Defaults to https://api.github.com
*
Expand Down Expand Up @@ -115,7 +110,7 @@ export namespace Octokit {

export declare class Octokit<
TVersion extends keyof Octokit.ApiVersions = "github.com",
TOptions extends Octokit.Options<TVersion> = Octokit.Options<TVersion>
TOptions extends Octokit.Options = Octokit.Options
> {
/**
* Pass one or multiple plugin functions to extend the `Octokit` class.
Expand Down Expand Up @@ -165,7 +160,7 @@ export declare class Octokit<
static withDefaults<
PredefinedOptionsOne,
ClassOne extends Constructor<
Octokit<TVersion, Octokit.Options<TVersion> & PredefinedOptionsOne>
Octokit<TVersion, Octokit.Options & PredefinedOptionsOne>
> &
ClassWithPlugins,
TVersion extends keyof Octokit.ApiVersions = "github.com"
Expand Down Expand Up @@ -209,9 +204,9 @@ export declare class Octokit<
/**
* Options passed to the constructor combined with the constructor defaults
*/
options: TOptions;
options: { version: TVersion } & TOptions;

constructor(options: TOptions);
constructor(options: { version?: TVersion } & TOptions);

request: RequestInterface<TVersion>;
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions tests/js/ghes-3.1-class/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ExtendOctokitWith, Octokit } from "@octokit-next/core";

import "@octokit-next/types-rest-api-ghes-3.1";

export const OctokitGhes31: ExtendOctokitWith<
Octokit<"ghes-3.1">,
{
defaults: {
baseUrl: string;
};
}
>;

// support import to be used as a class instance type
export type OctokitGhes31 = typeof OctokitGhes31;
File renamed without changes.
27 changes: 27 additions & 0 deletions tests/js/ghes-3.1-class/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expectType, expectNotType } from "tsd";

import { OctokitGhes31 } from "./index.js";

export async function test() {
new OctokitGhes31({});

const octokit = new OctokitGhes31({
baseUrl: "https://github.acme-inc.com/api/v3",
});

const emojisResponseGhes31 = await octokit.request("GET /emojis");
expectType<string>(emojisResponseGhes31.data["+1"]);
expectType<string>(emojisResponseGhes31.data["-1"]);
expectType<string>(emojisResponseGhes31.data["ghes-only"]);
expectType<never>(emojisResponseGhes31.data["dotcom-only"]);

expectType<never>(await octokit.request("GET /dotcom-only"));
expectNotType<never>(await octokit.request("GET /new-endpoint"));

const { headers } = await octokit.request("GET /emojis");
expectType<string>(headers["x-github-enterprise-version"]);
expectType<never>(headers["x-dotcom-only"]);

expectNotType<never>(await octokit.request("GET /ghes-only"));
expectNotType<never>(await octokit.request("GET /new-ghes-only"));
}
16 changes: 1 addition & 15 deletions tests/js/ghes-3.1/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1 @@
import { ExtendOctokitWith, Octokit } from "@octokit-next/core";

import "@octokit-next/types-rest-api-ghes-3.1";

export const OctokitGhes31: ExtendOctokitWith<
Octokit<"ghes-3.1">,
{
defaults: {
baseUrl: string;
};
}
>;

// support import to be used as a class instance type
export type OctokitGhes31 = typeof OctokitGhes31;
export {};
29 changes: 10 additions & 19 deletions tests/js/ghes-3.1/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
import { expectType, expectNotType } from "tsd";

import { OctokitGhes31 } from "./index.js";
import { Octokit } from "@octokit-next/core";

export async function test() {
new OctokitGhes31({});
import "@octokit-next/types-rest-api-ghes-3.1";

const octokit = new OctokitGhes31({
baseUrl: "https://github.acme-inc.com/api/v3",
export async function test() {
const octokit = new Octokit({
version: "ghes-3.1",
});

const emojisResponseGhes31 = await octokit.request("GET /emojis");
expectType<string>(emojisResponseGhes31.data["+1"]);
expectType<string>(emojisResponseGhes31.data["-1"]);
expectType<string>(emojisResponseGhes31.data["ghes-only"]);
expectType<never>(emojisResponseGhes31.data["dotcom-only"]);

expectType<never>(await octokit.request("GET /dotcom-only"));
expectNotType<never>(await octokit.request("GET /new-endpoint"));

const { headers } = await octokit.request("GET /emojis");
expectType<string>(headers["x-github-enterprise-version"]);
expectType<never>(headers["x-dotcom-only"]);
const dotcomOnlyResponse = await octokit.request("GET /dotcom-only");
expectType<never>(dotcomOnlyResponse);

expectNotType<never>(await octokit.request("GET /ghes-only"));
expectNotType<never>(await octokit.request("GET /new-ghes-only"));
const ghesOnlyResponse = await octokit.request("GET /ghes-only");
expectType<boolean>(ghesOnlyResponse.data.ok);
expectType<never>(ghesOnlyResponse.headers["x-dotcom-only"]);
}

0 comments on commit 8f6de6c

Please sign in to comment.