Skip to content

Commit 5e6daaa

Browse files
authored
Merge pull request #1381 from paulmillr/event-types
feat: strongly type event emitter methods
2 parents e9cd7f6 + 7958696 commit 5e6daaa

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/index.ts

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
EMPTY_FN,
1414
STR_CLOSE,
1515
STR_END,
16+
WatchHandlers,
1617
} from './handler.js';
1718

1819
type AWF = {
@@ -58,7 +59,8 @@ export type FSWInstanceOptions = BasicOpts & {
5859
};
5960

6061
export type ThrottleType = 'readdir' | 'watch' | 'add' | 'remove' | 'change';
61-
export type EmitArgs = [EventName, Path | Error, any?, any?, any?];
62+
export type EmitArgs = [Path | Error, Stats?];
63+
export type EmitArgsWithName = [EventName, ...EmitArgs];
6264
export type MatchFunction = (val: string, stats?: Stats) => boolean;
6365
export interface MatcherObject {
6466
path: string;
@@ -295,6 +297,17 @@ export class WatchHelper {
295297
}
296298
}
297299

300+
export interface FSWatcherKnownEventMap {
301+
[EV.READY]: [];
302+
[EV.RAW]: Parameters<WatchHandlers['rawEmitter']>;
303+
[EV.ERROR]: Parameters<WatchHandlers['errHandler']>;
304+
[EV.ALL]: [EventName, ...EmitArgs];
305+
}
306+
307+
export type FSWatcherEventMap = FSWatcherKnownEventMap & {
308+
[k in Exclude<EventName, keyof FSWatcherKnownEventMap>]: EmitArgs;
309+
};
310+
298311
/**
299312
* Watches files & directories for changes. Emitted events:
300313
* `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
@@ -303,7 +316,7 @@ export class WatchHelper {
303316
* .add(directories)
304317
* .on('add', path => log('File', path, 'was added'))
305318
*/
306-
export class FSWatcher extends EventEmitter {
319+
export class FSWatcher extends EventEmitter<FSWatcherEventMap> {
307320
closed: boolean;
308321
options: FSWInstanceOptions;
309322

@@ -315,13 +328,13 @@ export class FSWatcher extends EventEmitter {
315328
_watched: Map<string, DirEntry>;
316329

317330
_pendingWrites: Map<string, any>;
318-
_pendingUnlinks: Map<string, EmitArgs>;
331+
_pendingUnlinks: Map<string, EmitArgsWithName>;
319332
_readyCount: number;
320333
_emitReady: () => void;
321334
_closePromise?: Promise<void>;
322335
_userIgnored?: MatchFunction;
323336
_readyEmitted: boolean;
324-
_emitRaw: () => void;
337+
_emitRaw: WatchHandlers['rawEmitter'];
325338
_boundRemove: (dir: string, item: string) => void;
326339

327340
_nodeFsHandler: NodeFsHandler;
@@ -567,8 +580,8 @@ export class FSWatcher extends EventEmitter {
567580
}
568581

569582
emitWithAll(event: EventName, args: EmitArgs) {
570-
this.emit(...args);
571-
if (event !== EV.ERROR) this.emit(EV.ALL, ...args);
583+
this.emit(event, ...args);
584+
if (event !== EV.ERROR) this.emit(EV.ALL, event, ...args);
572585
}
573586

574587
// Common helpers
@@ -588,7 +601,7 @@ export class FSWatcher extends EventEmitter {
588601
const opts = this.options;
589602
if (isWindows) path = sysPath.normalize(path);
590603
if (opts.cwd) path = sysPath.relative(opts.cwd, path);
591-
const args: EmitArgs = [event, path];
604+
const args: EmitArgs = [path];
592605
if (stats != null) args.push(stats);
593606

594607
const awf = opts.awaitWriteFinish;
@@ -600,10 +613,10 @@ export class FSWatcher extends EventEmitter {
600613

601614
if (opts.atomic) {
602615
if (event === EV.UNLINK) {
603-
this._pendingUnlinks.set(path, args);
616+
this._pendingUnlinks.set(path, [event, ...args]);
604617
setTimeout(
605618
() => {
606-
this._pendingUnlinks.forEach((entry: EmitArgs, path: Path) => {
619+
this._pendingUnlinks.forEach((entry: EmitArgsWithName, path: Path) => {
607620
this.emit(...entry);
608621
this.emit(EV.ALL, ...entry);
609622
this._pendingUnlinks.delete(path);
@@ -614,21 +627,21 @@ export class FSWatcher extends EventEmitter {
614627
return this;
615628
}
616629
if (event === EV.ADD && this._pendingUnlinks.has(path)) {
617-
event = args[0] = EV.CHANGE;
630+
event = EV.CHANGE;
618631
this._pendingUnlinks.delete(path);
619632
}
620633
}
621634

622635
if (awf && (event === EV.ADD || event === EV.CHANGE) && this._readyEmitted) {
623636
const awfEmit = (err?: Error, stats?: Stats) => {
624637
if (err) {
625-
event = args[0] = EV.ERROR;
626-
args[1] = err;
638+
event = EV.ERROR;
639+
args[0] = err;
627640
this.emitWithAll(event, args);
628641
} else if (stats) {
629642
// if stats doesn't exist the file must have been deleted
630-
if (args.length > 2) {
631-
args[2] = stats;
643+
if (args.length > 1) {
644+
args[1] = stats;
632645
} else {
633646
args.push(stats);
634647
}

0 commit comments

Comments
 (0)