diff --git a/packages/rxjs/spec-dtslint/observables/fromEvent-spec.ts b/packages/rxjs/spec-dtslint/observables/fromEvent-spec.ts index 8ef58e387c..081cc852bf 100644 --- a/packages/rxjs/spec-dtslint/observables/fromEvent-spec.ts +++ b/packages/rxjs/spec-dtslint/observables/fromEvent-spec.ts @@ -56,6 +56,13 @@ it('should support a node-style source', () => { const b = fromEvent(nodeStyleSource, "exit"); // $ExpectType Observable }); +it('should support a node-style source and symbol eventName', () => { + const SYMBOL_EVENT = Symbol(); + const source: NodeStyleEventEmitter = nodeStyleSource; + const a = fromEvent(nodeStyleSource, SYMBOL_EVENT); // $ExpectType Observable + const b = fromEvent(nodeStyleSource, SYMBOL_EVENT); // $ExpectType Observable +}); + it('should deprecate explicit type parameters for a node-style source', () => { const source: NodeStyleEventEmitter = nodeStyleSource; const a = fromEvent(nodeStyleSource, "exit"); // $ExpectNoDeprecation diff --git a/packages/rxjs/spec/observables/fromEvent-spec.ts b/packages/rxjs/spec/observables/fromEvent-spec.ts index 31f6f906dc..bb717e478b 100644 --- a/packages/rxjs/spec/observables/fromEvent-spec.ts +++ b/packages/rxjs/spec/observables/fromEvent-spec.ts @@ -121,6 +121,39 @@ describe('fromEvent', () => { expect(offHandler).to.equal(onHandler); }); + it('should pass symbol to "addListener" and "removeListener"', () => { + let onEventName; + let onHandler; + let offEventName; + let offHandler; + + const SYMBOL_EVENT = Symbol(); + + const obj = { + addListener(a: string | symbol, b: (...args: any[]) => void) { + onEventName = a; + onHandler = b; + return this; + }, + removeListener(a: string | symbol, b: (...args: any[]) => void) { + offEventName = a; + offHandler = b; + return this; + }, + }; + + const subscription = fromEvent(obj, SYMBOL_EVENT).subscribe(() => { + //noop + }); + + subscription.unsubscribe(); + + expect(onEventName).to.equal(SYMBOL_EVENT); + expect(typeof onHandler).to.equal('function'); + expect(offEventName).to.equal(onEventName); + expect(offHandler).to.equal(onHandler); + }); + it('should setup an event observable on objects with "addListener" and "removeListener" returning nothing', () => { let onEventName; let onHandler; diff --git a/packages/rxjs/src/internal/observable/fromEvent.ts b/packages/rxjs/src/internal/observable/fromEvent.ts index a9ecdf95fd..0c44fa98ca 100644 --- a/packages/rxjs/src/internal/observable/fromEvent.ts +++ b/packages/rxjs/src/internal/observable/fromEvent.ts @@ -77,12 +77,15 @@ export function fromEvent( resultSelector: (event: T) => R ): Observable; -export function fromEvent(target: NodeStyleEventEmitter | ArrayLike, eventName: string): Observable; +export function fromEvent( + target: NodeStyleEventEmitter | ArrayLike, + eventName: string | symbol +): Observable; /** @deprecated Do not specify explicit type parameters. Signatures with type parameters that cannot be inferred will be removed in v8. */ -export function fromEvent(target: NodeStyleEventEmitter | ArrayLike, eventName: string): Observable; +export function fromEvent(target: NodeStyleEventEmitter | ArrayLike, eventName: string | symbol): Observable; export function fromEvent( target: NodeStyleEventEmitter | ArrayLike, - eventName: string, + eventName: string | symbol, resultSelector: (...args: any[]) => R ): Observable; @@ -238,7 +241,7 @@ export function fromEvent( */ export function fromEvent( target: any, - eventName: string, + eventName: string | symbol, options?: EventListenerOptions | ((...args: any[]) => T), resultSelector?: (...args: any[]) => T ): Observable { @@ -248,7 +251,7 @@ export function fromEvent( } if (resultSelector) { - return fromEvent(target, eventName, options as EventListenerOptions).pipe(mapOneOrManyArgs(resultSelector)); + return fromEvent(target, eventName as string, options as EventListenerOptions).pipe(mapOneOrManyArgs(resultSelector)); } const isValidTarget = isNodeStyleEventEmitter(target) || isJQueryStyleEventEmitter(target) || isEventTarget(target); @@ -274,7 +277,13 @@ export function fromEvent( }); } -function doSubscribe(handler: (...args: any[]) => void, subscriber: Subscriber, subTarget: any, eventName: string, options: any) { +function doSubscribe( + handler: (...args: any[]) => void, + subscriber: Subscriber, + subTarget: any, + eventName: string | symbol, + options: any +) { const [addMethod, removeMethod] = getRegistryMethodNames(subTarget); if (!addMethod || !removeMethod) { throw new TypeError('Invalid event target');