@@ -13,26 +13,38 @@ export interface NodeStyleEventEmitter {
1313
1414export type NodeEventHandler = ( ...args : any [ ] ) => void ;
1515
16- export type JQueryStyleEventEmitter = {
16+ export interface JQueryStyleEventEmitter {
1717 on : ( eventName : string , handler : Function ) => void ;
1818 off : ( eventName : string , handler : Function ) => void ;
19- } ;
19+ }
20+
21+ export interface HasEventTargetAddRemove < E > {
22+ addEventListener ( type : string , listener : ( ( evt : E ) => void ) | null , options ?: boolean | AddEventListenerOptions ) : void ;
23+ removeEventListener ( type : string , listener ?: ( ( evt : E ) => void ) | null , options ?: EventListenerOptions | boolean ) : void ;
24+ }
25+
26+ export type EventTargetLike < T > = HasEventTargetAddRemove < T > | NodeStyleEventEmitter | JQueryStyleEventEmitter ;
2027
21- export type EventTargetLike = EventTarget | NodeStyleEventEmitter | JQueryStyleEventEmitter | NodeList | HTMLCollection ;
28+ export type FromEventTarget < T > = EventTargetLike < T > | ArrayLike < EventTargetLike < T > > ;
2229
23- export type EventListenerOptions = {
30+ export interface EventListenerOptions {
2431 capture ?: boolean ;
2532 passive ?: boolean ;
2633 once ?: boolean ;
27- } | boolean ;
34+ }
35+
36+ export interface AddEventListenerOptions extends EventListenerOptions {
37+ once ?: boolean ;
38+ passive ?: boolean ;
39+ }
2840
2941/* tslint:disable:max-line-length */
30- export function fromEvent < T > ( target : EventTargetLike , eventName : string ) : Observable < T > ;
42+ export function fromEvent < T > ( target : FromEventTarget < T > , eventName : string ) : Observable < T > ;
3143/** @deprecated resultSelector no longer supported, pipe to map instead */
32- export function fromEvent < T > ( target : EventTargetLike , eventName : string , resultSelector : ( ...args : any [ ] ) => T ) : Observable < T > ;
33- export function fromEvent < T > ( target : EventTargetLike , eventName : string , options : EventListenerOptions ) : Observable < T > ;
44+ export function fromEvent < T > ( target : FromEventTarget < T > , eventName : string , resultSelector : ( ...args : any [ ] ) => T ) : Observable < T > ;
45+ export function fromEvent < T > ( target : FromEventTarget < T > , eventName : string , options : EventListenerOptions ) : Observable < T > ;
3446/** @deprecated resultSelector no longer supported, pipe to map instead */
35- export function fromEvent < T > ( target : EventTargetLike , eventName : string , options : EventListenerOptions , resultSelector : ( ...args : any [ ] ) => T ) : Observable < T > ;
47+ export function fromEvent < T > ( target : FromEventTarget < T > , eventName : string , options : EventListenerOptions , resultSelector : ( ...args : any [ ] ) => T ) : Observable < T > ;
3648/* tslint:enable:max-line-length */
3749
3850/**
@@ -138,7 +150,7 @@ export function fromEvent<T>(target: EventTargetLike, eventName: string, options
138150 * @see {@link bindNodeCallback }
139151 * @see {@link fromEventPattern }
140152 *
141- * @param {EventTargetLike } target The DOM EventTarget, Node.js
153+ * @param {FromEventTarget<T> } target The DOM EventTarget, Node.js
142154 * EventEmitter, JQuery-like event target, NodeList or HTMLCollection to attach the event handler to.
143155 * @param {string } eventName The event name of interest, being emitted by the
144156 * `target`.
@@ -147,7 +159,7 @@ export function fromEvent<T>(target: EventTargetLike, eventName: string, options
147159 * @name fromEvent
148160 */
149161export function fromEvent < T > (
150- target : EventTargetLike ,
162+ target : FromEventTarget < T > ,
151163 eventName : string ,
152164 options ?: EventListenerOptions | ( ( ...args : any [ ] ) => T ) ,
153165 resultSelector ?: ( ( ...args : any [ ] ) => T )
@@ -177,18 +189,18 @@ export function fromEvent<T>(
177189 } ) ;
178190}
179191
180- function setupSubscription < T > ( sourceObj : EventTargetLike , eventName : string ,
181- handler : Function , subscriber : Subscriber < T > ,
192+ function setupSubscription < T > ( sourceObj : FromEventTarget < T > , eventName : string ,
193+ handler : ( ... args : any [ ] ) => void , subscriber : Subscriber < T > ,
182194 options ?: EventListenerOptions ) {
183195 let unsubscribe : ( ) => void ;
184- if ( isNodeList ( sourceObj ) || isHTMLCollection ( sourceObj ) ) {
185- for ( let i = 0 , len = sourceObj . length ; i < len ; i ++ ) {
196+ if ( sourceObj && ( sourceObj as any ) . length ) {
197+ for ( let i = 0 , len = ( sourceObj as any ) . length ; i < len ; i ++ ) {
186198 setupSubscription ( sourceObj [ i ] , eventName , handler , subscriber , options ) ;
187199 }
188200 } else if ( isEventTarget ( sourceObj ) ) {
189201 const source = sourceObj ;
190- sourceObj . addEventListener ( eventName , handler as EventListener , options ) ;
191- unsubscribe = ( ) => source . removeEventListener ( eventName , handler as EventListener , options ) ;
202+ sourceObj . addEventListener ( eventName , handler , options ) ;
203+ unsubscribe = ( ) => source . removeEventListener ( eventName , handler , options ) ;
192204 } else if ( isJQueryStyleEventEmitter ( sourceObj ) ) {
193205 const source = sourceObj ;
194206 sourceObj . on ( eventName , handler ) ;
@@ -205,21 +217,13 @@ function setupSubscription<T>(sourceObj: EventTargetLike, eventName: string,
205217}
206218
207219function isNodeStyleEventEmitter ( sourceObj : any ) : sourceObj is NodeStyleEventEmitter {
208- return ! ! sourceObj && typeof sourceObj . addListener === 'function' && typeof sourceObj . removeListener === 'function' ;
220+ return sourceObj && typeof sourceObj . addListener === 'function' && typeof sourceObj . removeListener === 'function' ;
209221}
210222
211223function isJQueryStyleEventEmitter ( sourceObj : any ) : sourceObj is JQueryStyleEventEmitter {
212- return ! ! sourceObj && typeof sourceObj . on === 'function' && typeof sourceObj . off === 'function' ;
213- }
214-
215- function isNodeList ( sourceObj : any ) : sourceObj is NodeList {
216- return ! ! sourceObj && toString . call ( sourceObj ) === '[object NodeList]' ;
217- }
218-
219- function isHTMLCollection ( sourceObj : any ) : sourceObj is HTMLCollection {
220- return ! ! sourceObj && toString . call ( sourceObj ) === '[object HTMLCollection]' ;
224+ return sourceObj && typeof sourceObj . on === 'function' && typeof sourceObj . off === 'function' ;
221225}
222226
223- function isEventTarget ( sourceObj : any ) : sourceObj is EventTarget {
224- return ! ! sourceObj && typeof sourceObj . addEventListener === 'function' && typeof sourceObj . removeEventListener === 'function' ;
227+ function isEventTarget ( sourceObj : any ) : sourceObj is HasEventTargetAddRemove < any > {
228+ return sourceObj && typeof sourceObj . addEventListener === 'function' && typeof sourceObj . removeEventListener === 'function' ;
225229}
0 commit comments