import { typeGuard } from "tsafe/typeGuard"; export type EventTargetLike = EventTargetLike.HasEventTargetAddRemove | EventTargetLike.NodeStyleEventEmitter | EventTargetLike.JQueryStyleEventEmitter | EventTargetLike.RxJSSubject ; export namespace EventTargetLike { export type HTMLElement = HasEventTargetAddRemove & { innerText: string; }; export type Window = HasEventTargetAddRemove & { document: EventTargetLike.Document; }; export type Document = HasEventTargetAddRemove & { URL: string; }; export type RxJSSubject = { subscribe: (next: (data: T) => void) => RxJSSubject.Subscription; }; export namespace RxJSSubject { export type Subscription = { unsubscribe(): void; }; export function match(eventTarget: EventTargetLike): eventTarget is RxJSSubject { return ( typeGuard>(eventTarget, true) && eventTarget instanceof Object && typeof eventTarget.subscribe === "function" ); } } export type NodeStyleEventEmitter = NodeStyleEventEmitter.Compat | NodeStyleEventEmitter.Regular ; export namespace NodeStyleEventEmitter { export interface Regular { addListener: (eventName: string | symbol, handler: NodeEventHandler) => this; removeListener: (eventName: string | symbol, handler: NodeEventHandler) => this; }; export interface Compat { addListener: (eventName: string, handler: NodeEventHandler) => void | {}; removeListener: (eventName: string, handler: NodeEventHandler) => void | {}; } export declare type NodeEventHandler = (...args: any[]) => void; export function match(eventTarget: EventTargetLike): eventTarget is NodeStyleEventEmitter { return ( typeGuard(eventTarget, true) && eventTarget instanceof Object && typeof eventTarget.addListener === "function" && typeof eventTarget.removeListener === "function" ); } } export interface JQueryStyleEventEmitter { on: (eventName: string, handler: Function) => void; off: (eventName: string, handler: Function) => void; } export namespace JQueryStyleEventEmitter { export function match(eventTarget: EventTargetLike): eventTarget is JQueryStyleEventEmitter { return ( typeGuard(eventTarget, true) && eventTarget instanceof Object && typeof eventTarget.on === "function" && typeof eventTarget.off === "function" ); } } export interface HasEventTargetAddRemove { addEventListener(type: string, listener: ((evt: E) => void) | null, options?: boolean | HasEventTargetAddRemove.Options): void; removeEventListener(type: string, listener?: ((evt: E) => void) | null, options?: HasEventTargetAddRemove.Options | boolean): void; } export namespace HasEventTargetAddRemove { export interface Options { capture?: boolean; passive?: boolean; once?: boolean; } export function match(eventTarget: EventTargetLike): eventTarget is HasEventTargetAddRemove { return ( typeGuard>(eventTarget, true) && eventTarget instanceof Object && typeof eventTarget.addEventListener === "function" && typeof eventTarget.removeEventListener === "function" ); } } /* Return true if o can be a EventTargetLike */ export function canBe(o: any): boolean { try{ return ( HasEventTargetAddRemove.match(o) || NodeStyleEventEmitter.match(o) || JQueryStyleEventEmitter.match(o) || RxJSSubject.match(o) ); }catch{ return false; } } }