@@ -30,6 +30,11 @@ interface FakeYtNamespace {
3030 namespace : typeof YT ;
3131}
3232
33+ type ListenersStore < EventName extends keyof YT . Events > = { [ E in EventName ] ?: Set < Listener < E > > } ;
34+ type Listener < EventName extends keyof YT . Events > = NonNullable < YT . Events [ EventName ] > ;
35+ type ListenerArg < EventName extends keyof YT . Events > =
36+ Listener < EventName > extends YT . PlayerEventHandler < infer T > ? T : never ;
37+
3338export function createFakeYtNamespace ( ) : FakeYtNamespace {
3439 const playerSpy : jasmine . SpyObj < YT . Player > = jasmine . createSpyObj ( 'Player' , [
3540 'getPlayerState' ,
@@ -63,7 +68,7 @@ export function createFakeYtNamespace(): FakeYtNamespace {
6368 ] ) ;
6469
6570 let playerConfig : YT . PlayerOptions | undefined ;
66- const boundListeners = new Map < keyof YT . Events , Set < ( event : unknown ) => void > > ( ) ;
71+ const boundListeners : ListenersStore < keyof YT . Events > = { } ;
6772 const playerCtorSpy = jasmine . createSpy ( 'Player Constructor' ) ;
6873
6974 // The spy target function cannot be an arrow-function as this breaks when created through `new`.
@@ -72,28 +77,27 @@ export function createFakeYtNamespace(): FakeYtNamespace {
7277 return playerSpy ;
7378 } ) ;
7479
75- playerSpy . addEventListener . and . callFake (
76- ( name : keyof YT . Events , listener : ( e : unknown ) => unknown ) => {
77- if ( ! boundListeners . has ( name ) ) {
78- boundListeners . set ( name , new Set ( ) ) ;
79- }
80- boundListeners . get ( name ) ! . add ( listener ) ;
81- } ,
82- ) ;
80+ playerSpy . addEventListener . and . callFake ( ( name , listener ) => {
81+ const store : ListenersStore < typeof name > = boundListeners ;
82+ if ( ! store [ name ] ) {
83+ store [ name ] = new Set ( ) ;
84+ }
85+ store [ name ] . add ( listener ) ;
86+ } ) ;
8387
84- playerSpy . removeEventListener . and . callFake (
85- ( name : keyof YT . Events , listener : ( e : unknown ) => unknown ) => {
86- boundListeners . get ( name ) ?. delete ( listener ) ;
87- } ,
88- ) ;
88+ playerSpy . removeEventListener . and . callFake ( ( name , listener ) => {
89+ boundListeners [ name ] ?. delete ( listener ) ;
90+ } ) ;
8991
90- function eventHandlerFactory ( name : keyof YT . Events ) {
91- return ( arg : Object = { } ) => {
92+ function eventHandlerFactory < EventName extends keyof YT . Events > ( name : EventName ) {
93+ return ( arg = { } as ListenerArg < EventName > ) => {
9294 if ( ! playerConfig ) {
9395 throw new Error ( `Player not initialized before ${ name } called` ) ;
9496 }
9597
96- boundListeners . get ( name ) ?. forEach ( callback => callback ( arg ) ) ;
98+ boundListeners [ name ] ?. forEach ( callback =>
99+ ( callback as ( arg : ListenerArg < EventName > ) => void ) ( arg ) ,
100+ ) ;
97101 } ;
98102 }
99103
0 commit comments