Skip to content

Commit 60951f4

Browse files
committed
use type overload
1 parent 24ab73a commit 60951f4

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

packages/browser/src/helpers.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ export function ignoreNextOnError(): void {
3131
});
3232
}
3333

34+
// eslint-disable-next-line @typescript-eslint/ban-types
35+
type WrappableFunction = Function;
36+
37+
export function wrap<T extends WrappableFunction>(
38+
fn: T,
39+
options?: {
40+
mechanism?: Mechanism;
41+
},
42+
): WrappedFunction<T>;
43+
export function wrap<NonFunction>(
44+
fn: NonFunction,
45+
options?: {
46+
mechanism?: Mechanism;
47+
},
48+
): NonFunction;
3449
/**
3550
* Instruments the given function and sends an event to Sentry every time the
3651
* function throws an exception.
@@ -40,21 +55,20 @@ export function ignoreNextOnError(): void {
4055
* @returns The wrapped function.
4156
* @hidden
4257
*/
43-
// eslint-disable-next-line @typescript-eslint/ban-types
44-
export function wrap<T extends Function, NonFunctionType>(
45-
fn: T | NonFunctionType,
58+
export function wrap<T extends WrappableFunction, NonFunction>(
59+
fn: T | NonFunction,
4660
options: {
4761
mechanism?: Mechanism;
4862
} = {},
49-
): NonFunctionType | WrappedFunction<T> {
63+
): NonFunction | WrappedFunction<T> {
5064
// for future readers what this does is wrap a function and then create
5165
// a bi-directional wrapping between them.
5266
//
5367
// example: wrapped = wrap(original);
5468
// original.__sentry_wrapped__ -> wrapped
5569
// wrapped.__sentry_original__ -> original
5670

57-
function isFunction(fn: T | NonFunctionType): fn is T {
71+
function isFunction(fn: T | NonFunction): fn is T {
5872
return typeof fn === 'function';
5973
}
6074

packages/browser/test/helpers.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ describe('internal wrap()', () => {
1919
expect(wrap(num)).toBe(num);
2020
});
2121

22+
it('correctly infers types', () => {
23+
const a = wrap(42);
24+
expect(a > 40).toBe(true);
25+
26+
const b = wrap('42');
27+
expect(b.length).toBe(2);
28+
29+
const c = wrap(() => 42);
30+
expect(c()).toBe(42);
31+
expect(c.__sentry_original__).toBeInstanceOf(Function);
32+
});
33+
2234
it('should preserve correct function name when accessed', () => {
2335
const namedFunction = (): number => 1337;
2436
expect(wrap(namedFunction)).not.toBe(namedFunction);
@@ -149,7 +161,7 @@ describe('internal wrap()', () => {
149161
});
150162

151163
it('internal flags shouldnt be enumerable', () => {
152-
const fn = (() => 1337) as WrappedFunction;
164+
const fn = () => 1337;
153165
const wrapped = wrap(fn);
154166

155167
// Shouldn't show up in iteration
@@ -159,7 +171,7 @@ describe('internal wrap()', () => {
159171
expect(Object.keys(wrapped)).toEqual(expect.not.arrayContaining(['__sentry_wrapped__']));
160172
// But should be accessible directly
161173
expect(wrapped.__sentry_original__).toBe(fn);
162-
expect(fn.__sentry_wrapped__).toBe(wrapped);
174+
expect((fn as WrappedFunction).__sentry_wrapped__).toBe(wrapped);
163175
});
164176

165177
it('should only return __sentry_wrapped__ when it is a function', () => {

0 commit comments

Comments
 (0)