Skip to content

Commit ddb1fb1

Browse files
authored
Convert to TypeScript (#29)
1 parent 5be428b commit ddb1fb1

36 files changed

+835
-317
lines changed

.babelrc

+1-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
11
{
2-
"presets": ["@babel/env"],
3-
"env": {
4-
"production-esm": {
5-
"presets": [["@babel/env", { "modules": false }]]
6-
},
7-
"test": {
8-
"presets": [
9-
[
10-
"@babel/env",
11-
{
12-
"targets": {
13-
"node": "current"
14-
}
15-
}
16-
]
17-
]
18-
}
19-
}
2+
"presets": ["@babel/typescript", "@babel/env"]
203
}

.eslintrc.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
{
2-
"extends": "wojtekmaj"
2+
"extends": [
3+
"wojtekmaj",
4+
"plugin:@typescript-eslint/eslint-recommended",
5+
"plugin:@typescript-eslint/recommended"
6+
],
7+
"parser": "@typescript-eslint/parser",
8+
"plugins": ["@typescript-eslint"]
39
}

package.json

+12-6
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@
44
"description": "A collection of array-related async utilities.",
55
"main": "dist/cjs/index.js",
66
"module": "dist/esm/index.js",
7-
"source": "src/index.js",
7+
"source": "src/index.ts",
8+
"types": "src/index.ts",
89
"sideEffects": false,
910
"scripts": {
1011
"build": "yarn build-esm && yarn build-cjs",
11-
"build-esm": "BABEL_ENV=production-esm babel src -d dist/esm --ignore \"**/*.spec.js\"",
12-
"build-cjs": "BABEL_ENV=production-cjs babel src -d dist/cjs --ignore \"**/*.spec.js\"",
12+
"build-esm": "tsc --project tsconfig.build.json --outDir dist/esm --module esnext",
13+
"build-cjs": "tsc --project tsconfig.build.json --outDir dist/cjs --module commonjs",
1314
"clean": "rimraf dist",
1415
"jest": "jest",
1516
"lint": "eslint src",
1617
"postinstall": "husky install",
1718
"prepack": "yarn clean && yarn build",
1819
"prettier": "prettier --check . --cache",
19-
"test": "yarn lint && yarn prettier && yarn jest"
20+
"test": "yarn lint && yarn tsc && yarn prettier && yarn jest",
21+
"tsc": "tsc --noEmit"
2022
},
2123
"keywords": [
2224
"array",
@@ -30,16 +32,20 @@
3032
},
3133
"license": "MIT",
3234
"devDependencies": {
33-
"@babel/cli": "^7.15.0",
3435
"@babel/core": "^7.15.0",
3536
"@babel/preset-env": "^7.15.0",
37+
"@babel/preset-typescript": "^7.18.6",
38+
"@types/jest": "^29.0.0",
39+
"@typescript-eslint/eslint-plugin": "^5.41.0",
40+
"@typescript-eslint/parser": "^5.44.0",
3641
"eslint": "^8.26.0",
3742
"eslint-config-wojtekmaj": "^0.7.1",
3843
"husky": "^8.0.0",
3944
"jest": "^29.0.0",
4045
"prettier": "^2.7.0",
4146
"pretty-quick": "^3.1.0",
42-
"rimraf": "^3.0.0"
47+
"rimraf": "^3.0.0",
48+
"typescript": "^4.9.4"
4349
},
4450
"resolutions": {
4551
"semver@7.0.0": "^7.0.0"

src/every.spec.js renamed to src/every.spec.ts

+40-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import {
99
throws,
1010
} from '../test-utils';
1111

12-
function largerOrEqualThanZero(x) {
12+
function largerOrEqualThanZero(x: number) {
1313
return x >= 0;
1414
}
1515

16-
function largerOrEqualThanZeroInRandomTime(x) {
17-
return new Promise((resolve) =>
16+
function largerOrEqualThanZeroInRandomTime(x: number) {
17+
return new Promise<boolean>((resolve) =>
1818
setTimeout(() => {
1919
resolve(x >= 0);
2020
}, Math.random() * 100),
@@ -115,4 +115,41 @@ describe('asyncEvery()', () => {
115115

116116
await expect(() => asyncEvery(inputArr, mapper)).rejects.toThrow('Some error');
117117
});
118+
119+
it('returns type boolean given function that returns type Promise<boolean>', async () => {
120+
// @ts-expect-no-error
121+
const result: boolean = await asyncEvery(inputArr, largerOrEqualThanZeroInRandomTime);
122+
123+
expect(typeof result).toBe('boolean');
124+
});
125+
126+
it('returns type true given function that returns type Promise<true>', async () => {
127+
async function trueInRandomTime() {
128+
return new Promise<true>((resolve) =>
129+
setTimeout(() => {
130+
resolve(true);
131+
}, Math.random() * 100),
132+
);
133+
}
134+
135+
// @ts-expect-no-error
136+
const result: true = await asyncEvery(inputArr, trueInRandomTime);
137+
138+
expect(result).toBe(true);
139+
});
140+
141+
it('returns type false given function that returns type Promise<false>', async () => {
142+
async function falseInRandomTime() {
143+
return new Promise<false>((resolve) =>
144+
setTimeout(() => {
145+
resolve(false);
146+
}, Math.random() * 100),
147+
);
148+
}
149+
150+
// @ts-expect-no-error
151+
const result: false = await asyncEvery(inputArr, falseInRandomTime);
152+
153+
expect(result).toBe(false);
154+
});
118155
});

src/every.js renamed to src/every.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
import asyncForEach from './forEach';
22

3-
export default function asyncEvery(arr, fn) {
4-
let resolved;
3+
function asyncEvery<T>(
4+
arr: T[],
5+
fn: (cur: T, idx: number, arr: T[]) => Promise<true>,
6+
): Promise<true>;
7+
function asyncEvery<T>(
8+
arr: T[],
9+
fn: (cur: T, idx: number, arr: T[]) => Promise<false>,
10+
): Promise<false>;
11+
function asyncEvery<T>(
12+
arr: T[],
13+
fn: (cur: T, idx: number, arr: T[]) => Promise<boolean>,
14+
): Promise<boolean>;
15+
function asyncEvery<T>(
16+
arr: T[],
17+
fn: (cur: T, idx: number, arr: T[]) => Promise<boolean>,
18+
): Promise<boolean> {
19+
let resolved: boolean;
520
return new Promise((resolve, reject) => {
621
asyncForEach(
722
arr,
823
(cur, idx, arr2) =>
9-
new Promise((resolve2, reject2) => {
24+
new Promise<void>((resolve2, reject2) => {
1025
if (resolved) {
1126
return;
1227
}
@@ -31,3 +46,5 @@ export default function asyncEvery(arr, fn) {
3146
});
3247
});
3348
}
49+
50+
export default asyncEvery;

src/every_strict.js

-33
This file was deleted.

src/every_strict.spec.js renamed to src/every_strict.spec.ts

+41-4
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ import {
1212
throws,
1313
} from '../test-utils';
1414

15-
function largerOrEqualThanZero(x) {
15+
function largerOrEqualThanZero(x: number) {
1616
return x >= 0;
1717
}
1818

19-
function largerOrEqualThanZeroInRandomTime(x) {
20-
return new Promise((resolve) =>
19+
function largerOrEqualThanZeroInRandomTime(x: number) {
20+
return new Promise<boolean>((resolve) =>
2121
setTimeout(() => {
2222
resolve(x >= 0);
2323
}, Math.random() * 100),
@@ -26,7 +26,7 @@ function largerOrEqualThanZeroInRandomTime(x) {
2626

2727
describe('asyncEveryStrict()', () => {
2828
it('example from README works as described', async () => {
29-
const indexes = [];
29+
const indexes: number[] = [];
3030

3131
const largerThanZero = await asyncEveryStrict([1, 2, 3], async (el, index) => {
3232
indexes.push(index);
@@ -150,4 +150,41 @@ describe('asyncEveryStrict()', () => {
150150

151151
await expect(() => asyncEveryStrict(inputArr, mapper)).rejects.toThrow('Some error');
152152
});
153+
154+
it('returns type boolean given function that returns type Promise<boolean>', async () => {
155+
// @ts-expect-no-error
156+
const result: boolean = await asyncEveryStrict(inputArr, largerOrEqualThanZeroInRandomTime);
157+
158+
expect(typeof result).toBe('boolean');
159+
});
160+
161+
it('returns type true given function that returns type Promise<true>', async () => {
162+
async function trueInRandomTime() {
163+
return new Promise<true>((resolve) =>
164+
setTimeout(() => {
165+
resolve(true);
166+
}, Math.random() * 100),
167+
);
168+
}
169+
170+
// @ts-expect-no-error
171+
const result: true = await asyncEveryStrict(inputArr, trueInRandomTime);
172+
173+
expect(result).toBe(true);
174+
});
175+
176+
it('returns type false given function that returns type Promise<false>', async () => {
177+
async function falseInRandomTime() {
178+
return new Promise<false>((resolve) =>
179+
setTimeout(() => {
180+
resolve(false);
181+
}, Math.random() * 100),
182+
);
183+
}
184+
185+
// @ts-expect-no-error
186+
const result: false = await asyncEveryStrict(inputArr, falseInRandomTime);
187+
188+
expect(result).toBe(false);
189+
});
153190
});

src/every_strict.ts

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import asyncForEachStrict from './forEach_strict';
2+
3+
function asyncEveryStrict<T>(
4+
arr: T[],
5+
fn: (cur: T, idx: number, arr: T[]) => Promise<true>,
6+
): Promise<true>;
7+
function asyncEveryStrict<T>(
8+
arr: T[],
9+
fn: (cur: T, idx: number, arr: T[]) => Promise<false>,
10+
): Promise<false>;
11+
function asyncEveryStrict<T>(
12+
arr: T[],
13+
fn: (cur: T, idx: number, arr: T[]) => Promise<boolean>,
14+
): Promise<boolean>;
15+
function asyncEveryStrict<T>(
16+
arr: T[],
17+
fn: (cur: T, idx: number, arr: T[]) => Promise<boolean>,
18+
): Promise<boolean> {
19+
let resolved: boolean;
20+
return new Promise<boolean>((resolve, reject) => {
21+
asyncForEachStrict(
22+
arr,
23+
(cur, idx, arr2) =>
24+
new Promise<void>((resolve2, reject2) => {
25+
if (resolved) {
26+
return;
27+
}
28+
fn(cur, idx, arr2)
29+
.then((result) => {
30+
if (!result) {
31+
resolve(false);
32+
resolved = true;
33+
}
34+
resolve2();
35+
})
36+
.catch(reject2);
37+
}),
38+
)
39+
.then(() => {
40+
resolve(true);
41+
resolved = true;
42+
})
43+
.catch((error) => {
44+
reject(error);
45+
resolved = true;
46+
});
47+
});
48+
}
49+
50+
export default asyncEveryStrict;

src/filter.js

-20
This file was deleted.

src/filter.spec.js renamed to src/filter.spec.ts

+18
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,22 @@ describe('asyncFilter()', () => {
8787

8888
await expect(() => asyncFilter(inputArr, mapper)).rejects.toThrow('Some error');
8989
});
90+
91+
it('returns type T[] given function that returns type Promise<boolean>', async () => {
92+
// @ts-expect-no-error
93+
const result: number[] = await asyncFilter(inputArr, largerThanTwoInRandomTime);
94+
});
95+
96+
it('returns type never[] given function that returns type Promise<false>', async () => {
97+
async function falseInRandomTime() {
98+
return new Promise<false>((resolve) =>
99+
setTimeout(() => {
100+
resolve(false);
101+
}, Math.random() * 100),
102+
);
103+
}
104+
105+
// @ts-expect-no-error
106+
const result: never[] = await asyncFilter(inputArr, falseInRandomTime);
107+
});
90108
});

0 commit comments

Comments
 (0)