Skip to content

Commit cd00a69

Browse files
committed
fix(types): improved void handling for emit()
These type-level changes should improve the emit signature when `void` is used and when union types are used.
1 parent dfb9d34 commit cd00a69

2 files changed

Lines changed: 12 additions & 8 deletions

File tree

src/internal/types.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ReadonlySignal } from "@preact/signals";
22
import type { Patch } from "immer";
3+
import { EventParameters } from "src/listener.js";
34
import type { SigmaType } from "../framework.js";
45
import type { Draft, Immutable } from "../immer.js";
56
import { sigmaEventsBrand, sigmaRefBrand, sigmaStateBrand } from "./symbols.js";
@@ -73,9 +74,7 @@ export type EventMethods<TEvents extends AnyEvents | undefined> = [undefined] ex
7374
/** Registers a typed event listener and returns an unsubscribe function. */
7475
on<TEvent extends string & keyof TEvents>(
7576
name: TEvent,
76-
listener: [TEvents[TEvent]] extends [void]
77-
? () => void
78-
: (payload: TEvents[TEvent]) => void,
77+
listener: (...[detail]: EventParameters<TEvents[TEvent]>) => void,
7978
): Cleanup;
8079
};
8180

@@ -98,7 +97,7 @@ export type Emit<T extends SigmaDefinition, TOverrides extends Partial<SigmaDefi
9897
? [TEvents] extends [AnyEvents]
9998
? <TEvent extends string & keyof TEvents>(
10099
name: TEvent,
101-
...args: [TEvents[TEvent]] extends [void] ? [] : [payload: TEvents[TEvent]]
100+
...[detail]: EventParameters<TEvents[TEvent]>
102101
) => void
103102
: never
104103
: never;

src/listener.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ export type InferEventType<TTarget extends EventTarget> =
5151
| (InferListener<TTarget> extends { __eventType?: infer TEvent } ? string & TEvent : never)
5252
| (string & {});
5353

54+
/** Infers the detail parameter for a typed emit. */
55+
export type EventParameters<T> = [void] extends [T]
56+
? [detail?: T extends void ? undefined : T]
57+
: [undefined] extends [T]
58+
? [detail?: T]
59+
: [detail: T];
60+
5461
/**
5562
* A standalone typed event hub with `emit(...)` and `on(...)` methods and full
5663
* `EventTarget`, `listen(...)`, and `useListener(...)` compatibility.
@@ -66,11 +73,9 @@ export class SigmaTarget<TEvents extends AnyEvents = {}> extends EventTarget {
6673
*/
6774
emit<TEvent extends string & keyof TEvents>(
6875
name: TEvent,
69-
...args: [TEvents[TEvent]] extends [void] ? [] : [payload: TEvents[TEvent]]
76+
...[detail]: EventParameters<TEvents[TEvent]>
7077
) {
71-
this.dispatchEvent(
72-
args.length === 0 ? new Event(name) : new CustomEvent(name, { detail: args[0] }),
73-
);
78+
this.dispatchEvent(detail === undefined ? new Event(name) : new CustomEvent(name, { detail }));
7479
}
7580

7681
/**

0 commit comments

Comments
 (0)