Skip to content

Commit 79e1f59

Browse files
committed
ref: Make baseclient hooks typesafe when using generics
1 parent 0e337f6 commit 79e1f59

File tree

4 files changed

+25
-28
lines changed

4 files changed

+25
-28
lines changed

packages/core/src/baseclient.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import type {
99
Event,
1010
EventDropReason,
1111
EventHint,
12-
HookCallback,
13-
HookName,
12+
Hook,
1413
HookStore,
1514
Integration,
1615
IntegrationClass,
@@ -359,24 +358,21 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
359358
/**
360359
* @inheritDoc
361360
*/
362-
public on(hook: HookName, callback: HookCallback): void {
361+
public on<HookType extends Hook>(hook: HookType['name'], callback: HookType['callback']): void {
363362
if (!this._hooks[hook]) {
364363
this._hooks[hook] = [];
365364
}
366365

367-
// @ts-ignore we cannot enforce the callback to match the hook
368-
// while saving bundle size
369-
this._hooks[hook].push(callback);
366+
(this._hooks[hook] as HookType['callback'][]).push(callback);
370367
}
371368

372369
/**
373370
* @inheritDoc
374371
*/
375-
public emit(hook: HookName, ...args: Parameters<HookCallback>): void {
372+
public emit<HookType extends Hook>(hook: HookType['name'], ...args: Parameters<HookType['callback']>): void {
376373
if (this._hooks[hook]) {
377-
// @ts-ignore we cannot enforce the callback to match the hook
378-
// while saving bundle size
379-
this._hooks[hook].forEach((callback: HookCallback) => callback(...args));
374+
// @ts-ignore it does not like ...args, but we know this is correct
375+
(this._hooks[hook] as HookType['callback'][]).forEach(callback => callback(...args));
380376
}
381377
}
382378

packages/types/src/client.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { EventDropReason } from './clientreport';
22
import type { DataCategory } from './datacategory';
33
import type { DsnComponents } from './dsn';
44
import type { Event, EventHint } from './event';
5-
import type { EnvelopeHookCallback, EnvelopeHookName, TransactionHookCallback, TransactionHookName } from './hooks';
5+
import type { EnvelopeHook, TransactionHook } from './hooks';
66
import type { Integration, IntegrationClass } from './integration';
77
import type { ClientOptions } from './options';
88
import type { Scope } from './scope';
@@ -155,22 +155,22 @@ export interface Client<O extends ClientOptions = ClientOptions> {
155155
/**
156156
* Register a callback for transaction start and finish.
157157
*/
158-
on?(hook: TransactionHookName, callback: TransactionHookCallback): void;
158+
on?(hook: TransactionHook['name'], callback: TransactionHook['callback']): void;
159159

160160
/**
161161
* Register a callback for envelope creation and sending.
162162
*/
163-
on?(hook: EnvelopeHookName, callback: EnvelopeHookCallback): void;
163+
on?(hook: EnvelopeHook['name'], callback: EnvelopeHook['callback']): void;
164164

165165
/**
166166
* Fire a hook event for transaction start and finish. Expects to be given a transaction as the
167167
* second argument.
168168
*/
169-
emit?(hook: TransactionHookName, ...params: Parameters<TransactionHookCallback>): void;
169+
emit?(hook: TransactionHook['name'], ...params: Parameters<TransactionHook['callback']>): void;
170170

171171
/*
172172
* Fire a hook event for envelope creation and sending. Expects to be given an envelope as the
173173
* second argument.
174174
*/
175-
emit?(hook: EnvelopeHookName, ...params: Parameters<EnvelopeHookCallback>): void;
175+
emit?(hook: EnvelopeHook['name'], ...params: Parameters<EnvelopeHook['callback']>): void;
176176
}

packages/types/src/hooks.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import type { Envelope } from './envelope';
22
import type { Transaction } from './transaction';
33

4-
export type TransactionHookName = 'startTransaction' | 'transactionFinish';
5-
export type TransactionHookCallback = (transaction: Transaction) => void;
4+
// Hooks related to transaction start/finish
5+
export type TransactionHook = {
6+
name: 'startTransaction' | 'transactionFinish';
7+
callback: (transaction: Transaction) => void;
8+
};
69

7-
export type EnvelopeHookName = 'beforeEnvelope';
8-
export type EnvelopeHookCallback = (envelope: Envelope) => void;
10+
// Hooks related to envelope create and send
11+
export type EnvelopeHook = {
12+
name: 'beforeEnvelope';
13+
callback: (envelope: Envelope) => void;
14+
};
915

10-
export type HookName = TransactionHookName | EnvelopeHookName;
11-
export type HookCallback = TransactionHookCallback | EnvelopeHookCallback;
16+
export type Hook = TransactionHook | EnvelopeHook;
1217

13-
export type HookStoreItem<N extends HookName, C extends HookCallback> = Partial<{ [key in N]: C[] }>;
18+
export type HookStoreItem<T extends Hook> = Partial<Record<T['name'], T['callback'][]>>;
1419

15-
export type HookStore =
16-
// Hooks related to transaction start/finish
17-
HookStoreItem<TransactionHookName, TransactionHookCallback> &
18-
// Hooks related to envelope create and send
19-
HookStoreItem<EnvelopeHookName, EnvelopeHookCallback>;
20+
export type HookStore = HookStoreItem<EnvelopeHook> & HookStoreItem<TransactionHook>;

packages/types/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,4 @@ export type { WrappedFunction } from './wrappedfunction';
9696
export type { Instrumenter } from './instrumenter';
9797

9898
export type { BrowserClientReplayOptions } from './browseroptions';
99-
export type { HookStore, HookName, HookCallback } from './hooks';
99+
export type { HookStore, Hook, TransactionHook, EnvelopeHook } from './hooks';

0 commit comments

Comments
 (0)