Skip to content

Commit cc4700f

Browse files
committed
Add full TypeScript definitions and export them, add basic TS tests.
1 parent 3fd53f5 commit cc4700f

File tree

5 files changed

+231
-42
lines changed

5 files changed

+231
-42
lines changed

package-lock.json

Lines changed: 59 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"jsnext:main": "./dist/unfetch.mjs",
99
"umd:main": "./dist/unfetch.umd.js",
1010
"scripts": {
11-
"test": "eslint && NODE_OPTIONS=--experimental-vm-modules jest",
11+
"test": "eslint && tsc -p . --noEmit && NODE_OPTIONS=--experimental-vm-modules jest",
1212
"build": "microbundle src/index.mjs -f cjs,esm,umd && microbundle polyfill/polyfill.mjs -o polyfill/index.js -f cjs --no-sourcemap",
1313
"prepare": "npm run -s build",
1414
"release": "cross-var npm run build -s && cross-var git commit -am $npm_package_version && cross-var git tag $npm_package_version && git push && git push --tags && npm publish"
@@ -53,37 +53,41 @@
5353
"url": "http://localhost/"
5454
},
5555
"testMatch": [
56-
"<rootDir>/test/**/*.test.?(m)js?(x)"
56+
"<rootDir>/test/**/*.test.?(m)[jt]s?(x)"
5757
],
5858
"setupFiles": [
5959
"<rootDir>/test/_setup.js"
6060
],
6161
"moduleFileExtensions": [
6262
"mjs",
63-
"js"
63+
"js",
64+
"ts"
6465
],
6566
"transform": {
66-
"^.+\\.m?jsx?$": "babel-jest"
67+
"^.+\\.m?[jt]sx?$": "babel-jest"
6768
}
6869
},
6970
"babel": {
7071
"env": {
7172
"test": {
7273
"presets": [
73-
"@babel/preset-env"
74+
"@babel/preset-env",
75+
"@babel/preset-typescript"
7476
]
7577
}
7678
}
7779
},
7880
"devDependencies": {
7981
"@babel/core": "^7.20.7",
8082
"@babel/preset-env": "^7.20.2",
83+
"@babel/preset-typescript": "^7.18.6",
8184
"@types/jest": "^29.2.5",
8285
"@types/node": "^18.11.18",
8386
"cross-var": "^1.1.0",
8487
"eslint": "^8.30.0",
8588
"eslint-config-developit": "^1.2.0",
8689
"jest": "^29.3.1",
87-
"microbundle": "^0.15.1"
90+
"microbundle": "^0.15.1",
91+
"typescript": "^4.9.4"
8892
}
8993
}

src/index.d.ts

Lines changed: 92 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,102 @@
11
import {
2-
Body as NodeBody,
3-
Headers as NodeHeaders,
4-
Request as NodeRequest,
5-
Response as NodeResponse,
6-
RequestInit as NodeRequestInit
2+
Body as NodeBody,
3+
Headers as NodeHeaders,
4+
Request as NodeRequest,
5+
Response as NodeResponse,
6+
RequestInit as NodeRequestInit,
77
} from "node-fetch";
88

9-
declare namespace unfetch {
10-
export type IsomorphicHeaders = Headers | NodeHeaders;
11-
export type IsomorphicBody = Body | NodeBody;
12-
export type IsomorphicResponse = Response | NodeResponse;
13-
export type IsomorphicRequest = Request | NodeRequest;
14-
export type IsomorphicRequestInit = RequestInit | NodeRequestInit;
9+
/** @augments Headers */
10+
export interface UnfetchHeaders {
11+
keys: () => string[];
12+
entries: () => [string, string][];
13+
get: (key: string) => string | null;
14+
has: (key: string) => boolean;
15+
16+
/** @deprecated not supported by unfetch */
17+
append: never;
18+
/** @deprecated not supported by unfetch */
19+
delete: never;
20+
/** @deprecated not supported by unfetch */
21+
forEach: never;
22+
/** @deprecated not supported by unfetch */
23+
set: never;
24+
/** @deprecated not supported by unfetch */
25+
values: never;
26+
/** @deprecated not supported by unfetch */
27+
[Symbol.iterator]: never;
1528
}
1629

17-
type UnfetchResponse = {
18-
ok: boolean,
19-
statusText: string,
20-
status: number,
21-
url: string,
22-
text: () => Promise<string>,
23-
json: () => Promise<any>,
24-
blob: () => Promise<Blob>,
25-
clone: () => UnfetchResponse,
26-
headers: {
27-
keys: () => string[],
28-
entries: () => Array<[string, string]>,
29-
get: (key: string) => string | undefined,
30-
has: (key: string) => boolean,
31-
}
30+
/** @augments Response */
31+
export interface UnfetchResponse {
32+
ok: boolean;
33+
statusText: string;
34+
status: number;
35+
url: string;
36+
text: () => Promise<string>;
37+
json: () => Promise<any>;
38+
blob: () => Promise<Blob>;
39+
clone: () => UnfetchResponse;
40+
headers: UnfetchHeaders;
41+
42+
/** @deprecated not supported by unfetch */
43+
arrayBuffer: never;
44+
/** @deprecated not supported by unfetch */
45+
body: never;
46+
/** @deprecated not supported by unfetch */
47+
bodyUsed: never;
48+
/** @deprecated not supported by unfetch */
49+
formData: never;
50+
/** @deprecated not supported by unfetch */
51+
redirected: never;
52+
/** @deprecated not supported by unfetch */
53+
type: never;
54+
}
55+
56+
/** @augments RequestInit */
57+
export interface UnfetchRequestInit {
58+
method?: string;
59+
headers?: Record<string, string>;
60+
credentials?: "include" | "omit";
61+
body?: Parameters<XMLHttpRequest["send"]>[0];
62+
63+
/** @deprecated not supported by unfetch */
64+
cache?: never;
65+
/** @deprecated not supported by unfetch */
66+
integrity?: never;
67+
/** @deprecated not supported by unfetch */
68+
keepalive?: never;
69+
/** @deprecated not supported by unfetch */
70+
mode?: never;
71+
/** @deprecated not supported by unfetch */
72+
redirect?: never;
73+
/** @deprecated not supported by unfetch */
74+
referrer?: never;
75+
/** @deprecated not supported by unfetch */
76+
referrerPolicy?: never;
77+
/** @deprecated not supported by unfetch */
78+
signal?: never;
79+
/** @deprecated not supported by unfetch */
80+
window?: never;
3281
}
3382

34-
type Unfetch = (
35-
url: string,
36-
options?: {
37-
method?: string,
38-
headers?: Record<string, string>,
39-
credentials?: 'include' | 'omit',
40-
body?: Parameters<XMLHttpRequest["send"]>[0]
41-
}
42-
) => Promise<UnfetchResponse>
83+
export namespace Unfetch {
84+
export type IsomorphicHeaders = Headers | NodeHeaders;
85+
export type IsomorphicBody = Body | NodeBody;
86+
export type IsomorphicResponse = Response | NodeResponse;
87+
export type IsomorphicRequest = Request | NodeRequest;
88+
export type IsomorphicRequestInit = RequestInit | NodeRequestInit;
89+
90+
export type Headers = UnfetchHeaders | globalThis.Headers;
91+
export type Body = globalThis.Body;
92+
export type Response = UnfetchResponse | globalThis.Response;
93+
export type Request = UnfetchRequestInit | globalThis.Request;
94+
export type RequestInit = UnfetchRequestInit | globalThis.RequestInit;
95+
}
96+
97+
export interface Unfetch {
98+
(url: string | URL, options?: UnfetchRequestInit): Promise<UnfetchResponse>;
99+
}
43100

44101
declare const unfetch: Unfetch;
45102

test/typescript.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import unfetch, { Unfetch } from "..";
2+
import isomorphicUnfetch from "../packages/isomorphic-unfetch";
3+
4+
describe("TypeScript", () => {
5+
describe("browser", () => {
6+
beforeAll(() => {
7+
function XMLHttpRequest() {
8+
const res = {
9+
setRequestHeader: jest.fn(),
10+
getAllResponseHeaders: jest.fn().mockReturnValue(""),
11+
getResponseHeader: jest.fn().mockReturnValue(""),
12+
open: jest.fn((method, url) => {
13+
res.responseURL = url;
14+
}),
15+
send: jest.fn(),
16+
status: 200,
17+
statusText: "OK",
18+
get responseText() {
19+
return this.responseURL.replace(/^data:\,/, "");
20+
},
21+
responseURL: null,
22+
onload: () => {},
23+
};
24+
setTimeout(() => res.onload());
25+
return res;
26+
}
27+
28+
// @ts-ignore-next-line
29+
global.XMLHttpRequest = jest.fn(XMLHttpRequest);
30+
});
31+
32+
it("should have valid TypeScript types", async () => {
33+
const res: Unfetch.Response = await unfetch("data:,test");
34+
const text = await res.text();
35+
expect(text).toBe("test");
36+
});
37+
38+
// This fails because we're abusing Arrays as iterables:
39+
// it("should allow cast to Response", async () => {
40+
// const res: Response = await unfetch("data:,test");
41+
// const r = res.headers.keys()[0]
42+
// });
43+
});
44+
45+
describe("isomorphic-unfetch", () => {
46+
it("should allow use of standard types like Response", async () => {
47+
const res: Response = await isomorphicUnfetch(new URL("data:,test"));
48+
const blob: Blob = await res.blob();
49+
});
50+
51+
it("should accept Headers", async () => {
52+
isomorphicUnfetch("data:,test", {
53+
headers: new Headers({ a: "b" }),
54+
mode: "cors",
55+
});
56+
});
57+
});
58+
});

tsconfig.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"compilerOptions": {
3+
"noEmit": true,
4+
"checkJs": true,
5+
"target": "ESNext",
6+
"moduleResolution": "Node",
7+
"allowSyntheticDefaultImports": true,
8+
},
9+
"include": [
10+
"./**/*.ts"
11+
]
12+
}

0 commit comments

Comments
 (0)