Skip to content

Commit 49bf9b4

Browse files
committed
fix(types): resolve subclass factory return types to specific hook types
Each subclass factory (SyncHook, AsyncParallelHook, ...) was returning the generic `Hook<T, R, AdditionalOptions>` type, so consumers calling `new SyncHook()` got `Hook<...>` from JSDoc-generated types instead of the specific `SyncHook<...>` declared in the public `tapable.d.ts`. Mirror the public class declarations: each subclass file gets a typedef that re-exports the corresponding class from `tapable.d.ts` (with a `Type` suffix to avoid colliding with the factory function name in scope), then wires it as the factory's `@returns` and inner cast target. This keeps the V8 hidden-class optimization intact (still factory functions, no real `class extends Hook`) while aligning the JSDoc types with what tapable.d.ts already promises to consumers.
1 parent 73889c0 commit 49bf9b4

10 files changed

Lines changed: 117 additions & 20 deletions

lib/AsyncParallelBailHook.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").AsArray<T>} AsArray
2222
*/
2323

24+
/**
25+
* Mirror of the `AsyncParallelBailHook` class declared in `tapable.d.ts` for
26+
* use as the factory function's return type, so `new AsyncParallelBailHook(...)`
27+
* resolves to the specific subclass type instead of the generic `Hook`.
28+
* @template T
29+
* @template R
30+
* @template [AdditionalOptions=UnsetAdditionalOptions]
31+
* @typedef {import("../tapable").AsyncParallelBailHook<T, R, AdditionalOptions>} AsyncParallelBailHookType
32+
*/
33+
2434
class AsyncParallelBailHookCodeFactory extends HookCodeFactory {
2535
/**
2636
* @param {ContentOptions} options content generation options
@@ -107,7 +117,7 @@ function COMPILE(options) {
107117
* @template [AdditionalOptions=UnsetAdditionalOptions]
108118
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
109119
* @param {string=} name name of the hook
110-
* @returns {Hook<T, R, AdditionalOptions>} a new AsyncParallelBailHook instance
120+
* @returns {AsyncParallelBailHookType<T, R, AdditionalOptions>} a new AsyncParallelBailHook instance
111121
*/
112122
function AsyncParallelBailHook(
113123
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -119,7 +129,7 @@ function AsyncParallelBailHook(
119129
// @ts-expect-error for performance reasons
120130
hook._call = undefined;
121131
hook.call = undefined;
122-
return /** @type {Hook<T, R, AdditionalOptions>} */ (
132+
return /** @type {AsyncParallelBailHookType<T, R, AdditionalOptions>} */ (
123133
/** @type {unknown} */ (hook)
124134
);
125135
}

lib/AsyncParallelHook.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").AsArray<T>} AsArray
2222
*/
2323

24+
/**
25+
* Mirror of the `AsyncParallelHook` class declared in `tapable.d.ts` for use
26+
* as the factory function's return type, so `new AsyncParallelHook(...)`
27+
* resolves to the specific subclass type instead of the generic `Hook`.
28+
* @template T
29+
* @template [AdditionalOptions=UnsetAdditionalOptions]
30+
* @typedef {import("../tapable").AsyncParallelHook<T, AdditionalOptions>} AsyncParallelHookType
31+
*/
32+
2433
class AsyncParallelHookCodeFactory extends HookCodeFactory {
2534
/**
2635
* @param {ContentOptions} options content generation options
@@ -52,7 +61,7 @@ function COMPILE(options) {
5261
* @template [AdditionalOptions=UnsetAdditionalOptions]
5362
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
5463
* @param {string=} name name of the hook
55-
* @returns {Hook<T, void, AdditionalOptions>} a new AsyncParallelHook instance
64+
* @returns {AsyncParallelHookType<T, AdditionalOptions>} a new AsyncParallelHook instance
5665
*/
5766
function AsyncParallelHook(
5867
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -64,7 +73,7 @@ function AsyncParallelHook(
6473
// @ts-expect-error for performance reasons
6574
hook._call = undefined;
6675
hook.call = undefined;
67-
return /** @type {Hook<T, void, AdditionalOptions>} */ (
76+
return /** @type {AsyncParallelHookType<T, AdditionalOptions>} */ (
6877
/** @type {unknown} */ (hook)
6978
);
7079
}

lib/AsyncSeriesBailHook.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").AsArray<T>} AsArray
2222
*/
2323

24+
/**
25+
* Mirror of the `AsyncSeriesBailHook` class declared in `tapable.d.ts` for
26+
* use as the factory function's return type, so `new AsyncSeriesBailHook(...)`
27+
* resolves to the specific subclass type instead of the generic `Hook`.
28+
* @template T
29+
* @template R
30+
* @template [AdditionalOptions=UnsetAdditionalOptions]
31+
* @typedef {import("../tapable").AsyncSeriesBailHook<T, R, AdditionalOptions>} AsyncSeriesBailHookType
32+
*/
33+
2434
class AsyncSeriesBailHookCodeFactory extends HookCodeFactory {
2535
/**
2636
* @param {ContentOptions} options content generation options
@@ -58,7 +68,7 @@ function COMPILE(options) {
5868
* @template [AdditionalOptions=UnsetAdditionalOptions]
5969
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
6070
* @param {string=} name name of the hook
61-
* @returns {Hook<T, R, AdditionalOptions>} a new AsyncSeriesBailHook instance
71+
* @returns {AsyncSeriesBailHookType<T, R, AdditionalOptions>} a new AsyncSeriesBailHook instance
6272
*/
6373
function AsyncSeriesBailHook(
6474
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -70,7 +80,7 @@ function AsyncSeriesBailHook(
7080
// @ts-expect-error for performance reasons
7181
hook._call = undefined;
7282
hook.call = undefined;
73-
return /** @type {Hook<T, R, AdditionalOptions>} */ (
83+
return /** @type {AsyncSeriesBailHookType<T, R, AdditionalOptions>} */ (
7484
/** @type {unknown} */ (hook)
7585
);
7686
}

lib/AsyncSeriesHook.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").AsArray<T>} AsArray
2222
*/
2323

24+
/**
25+
* Mirror of the `AsyncSeriesHook` class declared in `tapable.d.ts` for use
26+
* as the factory function's return type, so `new AsyncSeriesHook(...)`
27+
* resolves to the specific subclass type instead of the generic `Hook`.
28+
* @template T
29+
* @template [AdditionalOptions=UnsetAdditionalOptions]
30+
* @typedef {import("../tapable").AsyncSeriesHook<T, AdditionalOptions>} AsyncSeriesHookType
31+
*/
32+
2433
class AsyncSeriesHookCodeFactory extends HookCodeFactory {
2534
/**
2635
* @param {ContentOptions} options content generation options
@@ -52,7 +61,7 @@ function COMPILE(options) {
5261
* @template [AdditionalOptions=UnsetAdditionalOptions]
5362
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
5463
* @param {string=} name name of the hook
55-
* @returns {Hook<T, void, AdditionalOptions>} a new AsyncSeriesHook instance
64+
* @returns {AsyncSeriesHookType<T, AdditionalOptions>} a new AsyncSeriesHook instance
5665
*/
5766
function AsyncSeriesHook(
5867
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -64,7 +73,7 @@ function AsyncSeriesHook(
6473
// @ts-expect-error for performance reasons
6574
hook._call = undefined;
6675
hook.call = undefined;
67-
return /** @type {Hook<T, void, AdditionalOptions>} */ (
76+
return /** @type {AsyncSeriesHookType<T, AdditionalOptions>} */ (
6877
/** @type {unknown} */ (hook)
6978
);
7079
}

lib/AsyncSeriesLoopHook.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").AsArray<T>} AsArray
2222
*/
2323

24+
/**
25+
* Mirror of the `AsyncSeriesLoopHook` class declared in `tapable.d.ts` for
26+
* use as the factory function's return type, so `new AsyncSeriesLoopHook(...)`
27+
* resolves to the specific subclass type instead of the generic `Hook`.
28+
* @template T
29+
* @template [AdditionalOptions=UnsetAdditionalOptions]
30+
* @typedef {import("../tapable").AsyncSeriesLoopHook<T, AdditionalOptions>} AsyncSeriesLoopHookType
31+
*/
32+
2433
class AsyncSeriesLoopHookCodeFactory extends HookCodeFactory {
2534
/**
2635
* @param {ContentOptions} options content generation options
@@ -52,7 +61,7 @@ function COMPILE(options) {
5261
* @template [AdditionalOptions=UnsetAdditionalOptions]
5362
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
5463
* @param {string=} name name of the hook
55-
* @returns {Hook<T, void, AdditionalOptions>} a new AsyncSeriesLoopHook instance
64+
* @returns {AsyncSeriesLoopHookType<T, AdditionalOptions>} a new AsyncSeriesLoopHook instance
5665
*/
5766
function AsyncSeriesLoopHook(
5867
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -64,7 +73,7 @@ function AsyncSeriesLoopHook(
6473
// @ts-expect-error for performance reasons
6574
hook._call = undefined;
6675
hook.call = undefined;
67-
return /** @type {Hook<T, void, AdditionalOptions>} */ (
76+
return /** @type {AsyncSeriesLoopHookType<T, AdditionalOptions>} */ (
6877
/** @type {unknown} */ (hook)
6978
);
7079
}

lib/AsyncSeriesWaterfallHook.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").AsArray<T>} AsArray
2222
*/
2323

24+
/**
25+
* Mirror of the `AsyncSeriesWaterfallHook` class declared in `tapable.d.ts`
26+
* for use as the factory function's return type, so
27+
* `new AsyncSeriesWaterfallHook(...)` resolves to the specific subclass type
28+
* instead of the generic `Hook`.
29+
* @template T
30+
* @template [R=AsArray<T>[0]]
31+
* @template [AdditionalOptions=UnsetAdditionalOptions]
32+
* @typedef {import("../tapable").AsyncSeriesWaterfallHook<T, R, AdditionalOptions>} AsyncSeriesWaterfallHookType
33+
*/
34+
2435
class AsyncSeriesWaterfallHookCodeFactory extends HookCodeFactory {
2536
/**
2637
* @param {ContentOptions} options content generation options
@@ -61,7 +72,7 @@ function COMPILE(options) {
6172
* @template [AdditionalOptions=UnsetAdditionalOptions]
6273
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
6374
* @param {string=} name name of the hook
64-
* @returns {Hook<T, R, AdditionalOptions>} a new AsyncSeriesWaterfallHookCodeFactory instance
75+
* @returns {AsyncSeriesWaterfallHookType<T, R, AdditionalOptions>} a new AsyncSeriesWaterfallHook instance
6576
*/
6677
function AsyncSeriesWaterfallHook(
6778
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -76,7 +87,7 @@ function AsyncSeriesWaterfallHook(
7687
// @ts-expect-error for performance reasons
7788
hook._call = undefined;
7889
hook.call = undefined;
79-
return /** @type {Hook<T, R, AdditionalOptions>} */ (
90+
return /** @type {AsyncSeriesWaterfallHookType<T, R, AdditionalOptions>} */ (
8091
/** @type {unknown} */ (hook)
8192
);
8293
}

lib/SyncBailHook.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ const HookCodeFactory = require("./HookCodeFactory");
2222
* @typedef {import("./Hook").ArgumentNames<T>} ArgumentNames
2323
*/
2424

25+
/**
26+
* Mirror of the `SyncBailHook` class declared in `tapable.d.ts` for use as
27+
* the factory function's return type, so `new SyncBailHook(...)` resolves to
28+
* the specific subclass type instead of the generic `Hook`.
29+
* @template T
30+
* @template R
31+
* @template [AdditionalOptions=UnsetAdditionalOptions]
32+
* @typedef {import("../tapable").SyncBailHook<T, R, AdditionalOptions>} SyncBailHookType
33+
*/
34+
2535
class SyncBailHookCodeFactory extends HookCodeFactory {
2636
/**
2737
* @param {ContentOptions} options content generation options
@@ -68,7 +78,7 @@ function COMPILE(options) {
6878
* @template [AdditionalOptions=UnsetAdditionalOptions]
6979
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
7080
* @param {string=} name name of the hook
71-
* @returns {Hook<T, R, AdditionalOptions>} a new AsyncParallelBailHook instance
81+
* @returns {SyncBailHookType<T, R, AdditionalOptions>} a new SyncBailHook instance
7282
*/
7383
function SyncBailHook(
7484
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -79,7 +89,7 @@ function SyncBailHook(
7989
hook.tapAsync = TAP_ASYNC;
8090
hook.tapPromise = TAP_PROMISE;
8191
hook.compile = COMPILE;
82-
return /** @type {Hook<T, R, AdditionalOptions>} */ (
92+
return /** @type {SyncBailHookType<T, R, AdditionalOptions>} */ (
8393
/** @type {unknown} */ (hook)
8494
);
8595
}

lib/SyncHook.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ const HookCodeFactory = require("./HookCodeFactory");
2222
* @typedef {import("./Hook").ArgumentNames<T>} ArgumentNames
2323
*/
2424

25+
/**
26+
* Mirror of the `SyncHook` class declared in `tapable.d.ts` for use as the
27+
* factory function's return type, so `new SyncHook(...)` resolves to the
28+
* specific subclass type instead of the generic `Hook`.
29+
* @template T
30+
* @template [R=void]
31+
* @template [AdditionalOptions=UnsetAdditionalOptions]
32+
* @typedef {import("../tapable").SyncHook<T, R, AdditionalOptions>} SyncHookType
33+
*/
34+
2535
class SyncHookCodeFactory extends HookCodeFactory {
2636
/**
2737
* @param {ContentOptions} options content generation options
@@ -63,7 +73,7 @@ function COMPILE(options) {
6373
* @template [AdditionalOptions=UnsetAdditionalOptions]
6474
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
6575
* @param {string=} name name of the hook
66-
* @returns {Hook<T, R, AdditionalOptions>} a new SyncHook instance
76+
* @returns {SyncHookType<T, R, AdditionalOptions>} a new SyncHook instance
6777
*/
6878
function SyncHook(
6979
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -74,7 +84,7 @@ function SyncHook(
7484
hook.tapAsync = TAP_ASYNC;
7585
hook.tapPromise = TAP_PROMISE;
7686
hook.compile = COMPILE;
77-
return /** @type {Hook<T, R, AdditionalOptions>} */ (
87+
return /** @type {SyncHookType<T, R, AdditionalOptions>} */ (
7888
/** @type {unknown} */ (hook)
7989
);
8090
}

lib/SyncLoopHook.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").ArgumentNames<T>} ArgumentNames
2222
*/
2323

24+
/**
25+
* Mirror of the `SyncLoopHook` class declared in `tapable.d.ts` for use as
26+
* the factory function's return type, so `new SyncLoopHook(...)` resolves
27+
* to the specific subclass type instead of the generic `Hook`.
28+
* @template T
29+
* @template [AdditionalOptions=UnsetAdditionalOptions]
30+
* @typedef {import("../tapable").SyncLoopHook<T, AdditionalOptions>} SyncLoopHookType
31+
*/
32+
2433
class SyncLoopHookCodeFactory extends HookCodeFactory {
2534
/**
2635
* @param {ContentOptions} options content generation options
@@ -61,7 +70,7 @@ function COMPILE(options) {
6170
* @template [AdditionalOptions=UnsetAdditionalOptions]
6271
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
6372
* @param {string=} name name of the hook
64-
* @returns {Hook<T, void, AdditionalOptions>} a new AsyncParallelBailHook instance
73+
* @returns {SyncLoopHookType<T, AdditionalOptions>} a new SyncLoopHook instance
6574
*/
6675
function SyncLoopHook(
6776
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -72,7 +81,7 @@ function SyncLoopHook(
7281
hook.tapAsync = TAP_ASYNC;
7382
hook.tapPromise = TAP_PROMISE;
7483
hook.compile = COMPILE;
75-
return /** @type {Hook<T, void, AdditionalOptions>} */ (
84+
return /** @type {SyncLoopHookType<T, AdditionalOptions>} */ (
7685
/** @type {unknown} */ (hook)
7786
);
7887
}

lib/SyncWaterfallHook.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ const HookCodeFactory = require("./HookCodeFactory");
2121
* @typedef {import("./Hook").ArgumentNames<T>} ArgumentNames
2222
*/
2323

24+
/**
25+
* Mirror of the `SyncWaterfallHook` class declared in `tapable.d.ts` for use
26+
* as the factory function's return type, so `new SyncWaterfallHook(...)`
27+
* resolves to the specific subclass type instead of the generic `Hook`.
28+
* @template T
29+
* @template [R=AsArray<T>[0]]
30+
* @template [AdditionalOptions=UnsetAdditionalOptions]
31+
* @typedef {import("../tapable").SyncWaterfallHook<T, R, AdditionalOptions>} SyncWaterfallHookType
32+
*/
33+
2434
class SyncWaterfallHookCodeFactory extends HookCodeFactory {
2535
/**
2636
* @param {ContentOptions} options content generation options
@@ -71,7 +81,7 @@ function COMPILE(options) {
7181
* @template [AdditionalOptions=UnsetAdditionalOptions]
7282
* @param {ArgumentNames<AsArray<T>>=} args argument names of the hook
7383
* @param {string=} name name of the hook
74-
* @returns {Hook<T, R, AdditionalOptions>} a new AsyncParallelBailHook instance
84+
* @returns {SyncWaterfallHookType<T, R, AdditionalOptions>} a new SyncWaterfallHook instance
7585
*/
7686
function SyncWaterfallHook(
7787
args = /** @type {ArgumentNames<AsArray<T>>} */ (/** @type {unknown} */ ([])),
@@ -85,7 +95,7 @@ function SyncWaterfallHook(
8595
hook.tapAsync = TAP_ASYNC;
8696
hook.tapPromise = TAP_PROMISE;
8797
hook.compile = COMPILE;
88-
return /** @type {Hook<T, R, AdditionalOptions>} */ (
98+
return /** @type {SyncWaterfallHookType<T, R, AdditionalOptions>} */ (
8999
/** @type {unknown} */ (hook)
90100
);
91101
}

0 commit comments

Comments
 (0)