GitHub

@@ -1,10 +1,14 @@

11

import { serial, flatHooks, mergeHooks } from './utils'

2-

import { LoggerT, hookFnT, configHooksT, deprecatedHookT, deprecatedHooksT } from './types'

2+

import type { LoggerT, DeprecatedHook, NestedHooks, HookCallback, HookKeys } from './types'

33

export * from './types'

445-

class Hookable {

6-

private _hooks: { [name: string]: hookFnT[] }

7-

private _deprecatedHooks: deprecatedHooksT

5+

class Hookable <

6+

_HooksT = Record<string, HookCallback>,

7+

HooksT = _HooksT & { error: (error: Error | any) => void },

8+

HookNameT extends HookKeys<HooksT> = HookKeys<HooksT>

9+

> {

10+

private _hooks: { [key: string]: HookCallback[] }

11+

private _deprecatedHooks: Record<string, DeprecatedHook<HooksT>>

812

private _logger: LoggerT | false

9131014

static mergeHooks: typeof mergeHooks

@@ -20,7 +24,7 @@ class Hookable {

2024

this.callHook = this.callHook.bind(this)

2125

}

222623-

hook (name: string, fn: hookFnT) {

27+

hook <NameT extends HookNameT>(name: NameT, fn: HooksT[NameT] & HookCallback) {

2428

if (!name || typeof fn !== 'function') {

2529

return () => {}

2630

}

@@ -56,19 +60,19 @@ class Hookable {

5660

}

5761

}

586259-

hookOnce (name: string, fn: hookFnT) {

63+

hookOnce <NameT extends HookNameT>(name: NameT, fn: HooksT[NameT] & HookCallback) {

6064

let _unreg

6165

let _fn = (...args) => {

6266

_unreg()

6367

_unreg = null

6468

_fn = null

6569

return fn(...args)

6670

}

67-

_unreg = this.hook(name, _fn)

71+

_unreg = this.hook(name, _fn as typeof fn)

6872

return _unreg

6973

}

707471-

removeHook (name: string, fn: hookFnT) {

75+

removeHook <NameT extends HookNameT> (name: NameT, fn: HooksT[NameT] & HookCallback) {

7276

if (this._hooks[name]) {

7377

const idx = this._hooks[name].indexOf(fn)

7478

@@ -82,16 +86,17 @@ class Hookable {

8286

}

8387

}

848885-

deprecateHook (name: string, deprecated: deprecatedHookT) {

89+

deprecateHook <NameT extends HookNameT> (name: NameT, deprecated: DeprecatedHook<HooksT>) {

8690

this._deprecatedHooks[name] = deprecated

8791

}

889289-

deprecateHooks (deprecatedHooks: deprecatedHooksT) {

93+

deprecateHooks (deprecatedHooks: Record<HookNameT, DeprecatedHook<HooksT>>) {

9094

Object.assign(this._deprecatedHooks, deprecatedHooks)

9195

}

929693-

addHooks (configHooks: configHooksT) {

94-

const hooks = flatHooks(configHooks)

97+

addHooks (configHooks: NestedHooks<HooksT>) {

98+

const hooks = flatHooks<HooksT>(configHooks)

99+

// @ts-ignore

95100

const removeFns = Object.keys(hooks).map(key => this.hook(key, hooks[key]))

9610197102

return () => {

@@ -101,21 +106,24 @@ class Hookable {

101106

}

102107

}

103108104-

removeHooks (configHooks: configHooksT) {

105-

const hooks = flatHooks(configHooks)

109+

removeHooks (configHooks: NestedHooks<HooksT>) {

110+

const hooks = flatHooks<HooksT>(configHooks)

106111

for (const key in hooks) {

112+

// @ts-ignore

107113

this.removeHook(key, hooks[key])

108114

}

109115

}

110116111-

async callHook (name: string, ...args: any) {

117+

// @ts-ignore HooksT[NameT] & HookCallback prevents typechecking

118+

async callHook <NameT extends HookNameT> (name: NameT, ...args: Parameters<HooksT[NameT]>) {

112119

if (!this._hooks[name]) {

113120

return

114121

}

115122

try {

116123

await serial(this._hooks[name], fn => fn(...args))

117124

} catch (err) {

118125

if (name !== 'error') {

126+

// @ts-ignore Stranger Things

119127

await this.callHook('error', err)

120128

}

121129

if (this._logger) {

Read the original on github.com ↗