Skip to content

Commit 9d5dc2b

Browse files
committed
refactor: fix overloads
1 parent a2332aa commit 9d5dc2b

3 files changed

Lines changed: 75 additions & 44 deletions

File tree

src/jsonpath.js

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,36 @@ class NewError extends Error {
193193
* @property {boolean} [ignoreEvalErrors=false]
194194
*/
195195

196+
196197
/**
197-
* @param {string|JSONPathOptions} opts If a string, will be treated as `expr`
198-
* @param {string} [expr] JSON path to evaluate
199-
* @param {AnyInput} [obj] JSON object to evaluate against
200-
* @param {JSONPathCallback} [callback] Passed 3 arguments: 1) desired payload
201-
* per `resultType`, 2) `"value"|"property"`, 3) Full returned object with
198+
* @overload
199+
* @param {string} opts JSON path to evaluate
200+
* @param {AnyInput} [expr] JSON object to evaluate against
201+
* @param {JSONPathCallback} [obj] Passed 3 arguments: 1) desired
202+
* payload per `resultType`, 2) `"value"|"property"`, 3) Full returned
203+
* object with all payloads
204+
* @param {OtherTypeCallback} [callback] If `@other()` is at the
205+
* end of one's query, this will be invoked with the value of the item,
206+
* its path, its parent, and its parent's property name, and it should
207+
* return a boolean indicating whether the supplied value belongs to the
208+
* "other" type or not (or it may handle transformations and return
209+
* `false`).
210+
* @param {undefined} [otherTypeCallback]
211+
* @returns {unknown|JSONPathClass}
212+
*/
213+
/**
214+
* @overload
215+
* @param {JSONPathOptions} opts If a string, will be treated as
216+
* `expr`
217+
* @returns {unknown|JSONPathClass}
218+
*/
219+
/**
220+
* @param {JSONPathOptions|string} opts If a string, will be treated as `expr`
221+
* @param {string|AnyInput} [expr] JSON path to evaluate
222+
* @param {AnyInput|JSONPathCallback} [obj] JSON object to evaluate against
223+
* @param {JSONPathCallback|OtherTypeCallback} [callback] Passed 3
224+
* arguments: 1) desired payload per `resultType`,
225+
* 2) `"value"|"property"`, 3) Full returned object with
202226
* all payloads
203227
* @param {OtherTypeCallback} [otherTypeCallback] If `@other()` is at the end
204228
* of one's query, this will be invoked with the value of the item, its
@@ -213,7 +237,13 @@ function JSONPath (opts, expr, obj, callback, otherTypeCallback) {
213237
if (opts && typeof opts === 'object') {
214238
return new JSONPathClass(opts);
215239
}
216-
return new JSONPathClass(opts, expr, obj, callback, otherTypeCallback);
240+
return new JSONPathClass(
241+
opts,
242+
expr,
243+
/** @type {JSONPathCallback|undefined} */ (obj),
244+
/** @type {OtherTypeCallback|undefined} */ (callback),
245+
/** @type {undefined} */ (otherTypeCallback)
246+
);
217247
} catch (e) {
218248
// eslint-disable-next-line no-restricted-syntax -- Within the file
219249
if (!(e instanceof NewError)) {
@@ -229,19 +259,18 @@ function JSONPath (opts, expr, obj, callback, otherTypeCallback) {
229259
class JSONPathClass {
230260
/**
231261
* @overload
232-
* @param {string} opts If a string, will be treated as
233-
* `expr`
234-
* @param {string} [expr] JSON path to evaluate
235-
* @param {JSON} [obj] JSON object to evaluate against
236-
* @param {JSONPathCallback} [callback] Passed 3 arguments: 1) desired
262+
* @param {string} opts JSON path to evaluate
263+
* @param {AnyInput} [expr] JSON object to evaluate against
264+
* @param {JSONPathCallback} [obj] Passed 3 arguments: 1) desired
237265
* payload per `resultType`, 2) `"value"|"property"`, 3) Full returned
238266
* object with all payloads
239-
* @param {OtherTypeCallback} [otherTypeCallback] If `@other()` is at the
267+
* @param {OtherTypeCallback} [callback] If `@other()` is at the
240268
* end of one's query, this will be invoked with the value of the item,
241269
* its path, its parent, and its parent's property name, and it should
242270
* return a boolean indicating whether the supplied value belongs to the
243271
* "other" type or not (or it may handle transformations and return
244272
* `false`).
273+
* @param {undefined} [otherTypeCallback]
245274
* @returns {JSONPath|JSONPathClass}
246275
*/
247276
/**
@@ -252,10 +281,11 @@ class JSONPathClass {
252281
/**
253282
* @param {null|string|JSONPathOptions} opts If a string, will be treated as
254283
* `expr`
255-
* @param {string} [expr] JSON path to evaluate
256-
* @param {AnyInput} [obj] JSON object to evaluate against
257-
* @param {JSONPathCallback} [callback] Passed 3 arguments: 1) desired
258-
* payload per `resultType`, 2) `"value"|"property"`, 3) Full returned
284+
* @param {string|AnyInput} [expr] JSON path to evaluate
285+
* @param {AnyInput|JSONPathCallback} [obj] JSON object to evaluate against
286+
* @param {JSONPathCallback|OtherTypeCallback} [callback] Passed 3
287+
* arguments: 1) desired payload per `resultType`,
288+
* 2) `"value"|"property"`, 3) Full returned
259289
* object with all payloads
260290
* @param {OtherTypeCallback} [otherTypeCallback] If `@other()` is at the
261291
* end of one's query, this will be invoked with the value of the item,
@@ -314,7 +344,10 @@ class JSONPathClass {
314344
: opts.ignoreEvalErrors;
315345
this.parent = opts.parent || null;
316346
this.parentProperty = opts.parentProperty || null;
317-
this.callback = opts.callback || callback || null;
347+
this.callback = opts.callback ||
348+
/** @type {JSONPathCallback} */
349+
(callback) ||
350+
null;
318351
this.otherTypeCallback = opts.otherTypeCallback ||
319352
otherTypeCallback ||
320353
function () {
@@ -353,7 +386,7 @@ class JSONPathClass {
353386
* @param {AnyInput} [json]
354387
* @param {JSONPathCallback|null} [callback]
355388
* @param {OtherTypeCallback} [otherTypeCallback]
356-
* @returns {ReturnObject|ReturnObject[]|undefined}
389+
* @returns {ReturnObject|ReturnObject[]|undefined|unknown}
357390
*/
358391
evaluate (
359392
expr, json, callback, otherTypeCallback
@@ -427,7 +460,10 @@ class JSONPathClass {
427460
return undefined;
428461
}
429462

430-
const exprList = JSONPath.toPathArray(expr);
463+
const exprList = JSONPath.toPathArray(
464+
/** @type {string} */
465+
(expr)
466+
);
431467
if (exprList[0] === '$' && exprList.length > 1) {
432468
exprList.shift();
433469
}
@@ -456,28 +492,23 @@ class JSONPathClass {
456492
}
457493
if (!wrap && result.length === 1 && !result[0].hasArrExpr) {
458494
const preferredOutput = this._getPreferredOutput(result[0]);
459-
return /** @type {ReturnObject|ReturnObject[]|undefined} */ (
460-
preferredOutput
461-
);
495+
return preferredOutput;
462496
}
463-
return /** @type {ReturnObject|ReturnObject[]|undefined} */ (
464-
/** @type {unknown} */ (
465-
result.reduce(
466-
(
467-
/** @type {UnknownResult[]} */ rslt,
468-
/** @type {ReturnObject} */ ea
469-
) => {
470-
const valOrPath = this._getPreferredOutput(ea);
471-
if (flatten && Array.isArray(valOrPath)) {
472-
rslt = rslt.concat(valOrPath);
473-
} else {
474-
rslt.push(valOrPath);
475-
}
476-
return rslt;
477-
}, []
478-
)
479-
)
497+
const reduced = result.reduce(
498+
(rslt, ea) => {
499+
const valOrPath = this._getPreferredOutput(ea);
500+
if (flatten && Array.isArray(valOrPath)) {
501+
rslt = rslt.concat(valOrPath);
502+
} else {
503+
rslt.push(valOrPath);
504+
}
505+
return rslt;
506+
},
507+
/** @type {UnknownResult[]} */
508+
([])
480509
);
510+
511+
return reduced;
481512
}
482513

483514
// PRIVATE METHODS

test/test.api.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,21 @@ describe('JSONPath - API', function () {
6767
}));
6868
let result = jp.evaluate();
6969
assert.deepEqual(result, expected);
70-
jp = jsonpath({
70+
jp = /** @type {JSONPathClass} */ (jsonpath({
7171
json,
7272
path: 'store.book[*].author',
7373
autostart: false
74-
});
74+
}));
7575
result = jp.evaluate();
7676
assert.deepEqual(result, expected);
7777
});
7878

7979
it('should test defaults with `evaluate` object and `autostart: false`', () => {
8080
const books = json.store.book;
8181
const expected = [books[0].author, books[1].author, books[2].author, books[3].author];
82-
const jp = jsonpath({
82+
const jp = /** @type {JSONPathClass} */ (jsonpath({
8383
autostart: false
84-
});
84+
}));
8585
const result = jp.evaluate({
8686
json,
8787
path: '$.store.book[*].author',

test/test.errors.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ checkBuiltInVMAndNodeVM(function (vmType, setBuiltInState) {
2727

2828
it('should throw with a bad result type', () => {
2929
expect(() => {
30+
// @ts-expect-error Bad argument
3031
jsonpath({
3132
json: {children: [5]},
3233
path: '$..children',
33-
// @ts-expect-error Bad argument
3434
resultType: 'badType'
3535
});
3636
}).to.throw(TypeError, 'Unknown result type');

0 commit comments

Comments
 (0)