Skip to content

Commit 17acf10

Browse files
authored
feat: Add optional defaults type parameter to EndpointInterface & RequestInterface, pass on option types from .defaults(options) (#48)
1 parent 7b35b72 commit 17acf10

File tree

8 files changed

+195
-61
lines changed

8 files changed

+195
-61
lines changed

README.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,24 @@
66
[![Build Status](https://github.com/octokit/types.ts/workflows/Test/badge.svg)](https://github.com/octokit/types.ts/actions?workflow=Test)
77
[![Greenkeeper](https://badges.greenkeeper.io/octokit/types.ts.svg)](https://greenkeeper.io/)
88

9+
<!-- toc -->
10+
11+
- [Usage](#usage)
12+
- [Examples](#examples)
13+
- [Get parameter and response data types for a REST API endpoint](#get-parameter-and-response-data-types-for-a-rest-api-endpoint)
14+
- [Get response types from endpoint methods](#get-response-types-from-endpoint-methods)
15+
- [Contributing](#contributing)
16+
- [License](#license)
17+
18+
<!-- tocstop -->
19+
920
## Usage
1021

11-
Get parameter and response data types for a REST API endpoint
22+
See all exported types at https://octokit.github.io/types.ts
23+
24+
## Examples
25+
26+
### Get parameter and response data types for a REST API endpoint
1227

1328
```ts
1429
import { Endpoints } from "./src";
@@ -23,7 +38,7 @@ async function listRepos(
2338
}
2439
```
2540

26-
Get response types from endpoint methods
41+
### Get response types from endpoint methods
2742

2843
```ts
2944
import {
@@ -41,8 +56,6 @@ type CreateLabelResponseDataType = GetResponseDataTypeFromEndpointMethod<
4156
>;
4257
```
4358

44-
See https://octokit.github.io/types.ts for all exported types
45-
4659
## Contributing
4760

4861
See [CONTRIBUTING.md](CONTRIBUTING.md)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"lint": "prettier --check '{src,test,scripts}/**/*.{js,ts,json}' README.md package.json !src/generated/* !scripts/update-endpoints/generated/*",
1515
"lint:fix": "prettier --write '{src,test,scripts}/**/*.{js,ts,json}' README.md package.json !src/generated/* !scripts/update-endpoints/generated/*",
1616
"pretest": "npm run -s lint",
17-
"test": "npx tsc --noEmit --declaration src/index.ts",
17+
"test": "npx tsc --noEmit --declaration src/index.ts test.ts",
1818
"update-endpoints": "npm-run-all update-endpoints:*",
1919
"update-endpoints:fetch-json": "node scripts/update-endpoints/fetch-json",
2020
"update-endpoints:typescript": "node scripts/update-endpoints/typescript"

scripts/update-endpoints/templates/endpoints.ts.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type {{request.name}} = {
4141
{{/each}}
4242

4343
{{#childParams}}
44-
export type {{paramTypeName}} = {
44+
type {{paramTypeName}} = {
4545
{{#params}}
4646
{{{name this}}}: {{{type this}}}
4747
{{/params}}

src/EndpointInterface.ts

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,50 @@
11
import { EndpointDefaults } from "./EndpointDefaults";
2-
import { EndpointOptions } from "./EndpointOptions";
32
import { RequestOptions } from "./RequestOptions";
43
import { RequestParameters } from "./RequestParameters";
54
import { Route } from "./Route";
65

76
import { Endpoints } from "./generated/Endpoints";
87

9-
export interface EndpointInterface {
8+
export interface EndpointInterface<D extends object = object> {
109
/**
1110
* Transforms a GitHub REST API endpoint into generic request options
1211
*
13-
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
12+
* @param {object} endpoint Must set `url` unless it's set defaults. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
1413
*/
15-
(options: EndpointOptions): RequestOptions;
14+
<O extends RequestParameters = RequestParameters>(
15+
options: O & { method?: string } & ("url" extends keyof D
16+
? { url?: string }
17+
: { url: string })
18+
): RequestOptions & Pick<D & O, keyof RequestOptions>;
1619

1720
/**
1821
* Transforms a GitHub REST API endpoint into generic request options
1922
*
2023
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
2124
* @param {object} [parameters] URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
2225
*/
23-
<R extends Route>(
24-
route: keyof Endpoints | R,
25-
options?: R extends keyof Endpoints
26+
<
27+
R extends Route,
28+
P extends RequestParameters = R extends keyof Endpoints
2629
? Endpoints[R]["parameters"] & RequestParameters
2730
: RequestParameters
28-
): R extends keyof Endpoints ? Endpoints[R]["request"] : RequestOptions;
31+
>(
32+
route: keyof Endpoints | R,
33+
parameters?: P
34+
): (R extends keyof Endpoints ? Endpoints[R]["request"] : RequestOptions) &
35+
Pick<P, keyof RequestOptions>;
2936

3037
/**
3138
* Object with current default route and parameters
3239
*/
33-
DEFAULTS: EndpointDefaults;
40+
DEFAULTS: D & EndpointDefaults;
3441

3542
/**
36-
* Returns a new `endpoint` with updated route and parameters
43+
* Returns a new `endpoint` interface with new defaults
3744
*/
38-
defaults: (newDefaults: RequestParameters) => EndpointInterface;
45+
defaults: <O extends RequestParameters = RequestParameters>(
46+
newDefaults: O
47+
) => EndpointInterface<D & O>;
3948

4049
merge: {
4150
/**
@@ -46,22 +55,36 @@ export interface EndpointInterface {
4655
* @param {object} [parameters] URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
4756
*
4857
*/
49-
(route: Route, parameters?: RequestParameters): EndpointDefaults;
58+
<
59+
R extends Route,
60+
P extends RequestParameters = R extends keyof Endpoints
61+
? Endpoints[R]["parameters"] & RequestParameters
62+
: RequestParameters
63+
>(
64+
route: keyof Endpoints | R,
65+
parameters?: P
66+
): D &
67+
(R extends keyof Endpoints
68+
? Endpoints[R]["request"] & Endpoints[R]["parameters"]
69+
: EndpointDefaults) &
70+
P;
5071

5172
/**
5273
* Merges current endpoint defaults with passed route and parameters,
5374
* without transforming them into request options.
5475
*
5576
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
5677
*/
57-
(options: RequestParameters): EndpointDefaults;
78+
<P extends RequestParameters = RequestParameters>(
79+
options: P
80+
): EndpointDefaults & D & P;
5881

5982
/**
6083
* Returns current default options.
6184
*
6285
* @deprecated use endpoint.DEFAULTS instead
6386
*/
64-
(): EndpointDefaults;
87+
(): D & EndpointDefaults;
6588
};
6689

6790
/**
@@ -70,5 +93,7 @@ export interface EndpointInterface {
7093
*
7194
* @param {object} options `method`, `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
7295
*/
73-
parse: (options: EndpointDefaults) => RequestOptions;
96+
parse: <O extends EndpointDefaults = EndpointDefaults>(
97+
options: O
98+
) => RequestOptions & Pick<O, keyof RequestOptions>;
7499
}

src/RequestInterface.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ import { Route } from "./Route";
66

77
import { Endpoints } from "./generated/Endpoints";
88

9-
export interface RequestInterface {
9+
export interface RequestInterface<D extends object = object> {
1010
/**
1111
* Sends a request based on endpoint options
1212
*
1313
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
1414
*/
15-
<T = any>(options: EndpointOptions): Promise<OctokitResponse<T>>;
15+
<T = any, O extends RequestParameters = RequestParameters>(
16+
options: O & { method?: string } & ("url" extends keyof D
17+
? { url?: string }
18+
: { url: string })
19+
): Promise<OctokitResponse<T>>;
1620

1721
/**
1822
* Sends a request based on endpoint options
@@ -30,12 +34,14 @@ export interface RequestInterface {
3034
: Promise<OctokitResponse<any>>;
3135

3236
/**
33-
* Returns a new `endpoint` with updated route and parameters
37+
* Returns a new `request` with updated route and parameters
3438
*/
35-
defaults: (newDefaults: RequestParameters) => RequestInterface;
39+
defaults: <O extends RequestParameters = RequestParameters>(
40+
newDefaults: O
41+
) => RequestInterface<D & O>;
3642

3743
/**
3844
* Octokit endpoint API, see {@link https://github.com/octokit/endpoint.js|@octokit/endpoint}
3945
*/
40-
endpoint: EndpointInterface;
46+
endpoint: EndpointInterface<D>;
4147
}

src/RequestParameters.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ export type RequestParameters = {
4242
* 3. Request body if `parameter` is `'data'`
4343
* 4. JSON in the request body in the form of `body[parameter]` unless `parameter` key is `'data'`
4444
*/
45-
[parameter: string]: any;
45+
[parameter: string]: unknown;
4646
};

0 commit comments

Comments
 (0)