Skip to content

Commit 44c4fe5

Browse files
committed
refactor(multiple): improve types
1 parent 04c922b commit 44c4fe5

File tree

4 files changed

+38
-31
lines changed

4 files changed

+38
-31
lines changed

Diff for: src/google-maps/map-event-manager.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import {switchMap} from 'rxjs/operators';
1212

1313
type MapEventManagerTarget =
1414
| {
15-
addListener: (
15+
addListener<T>(
1616
name: string,
17-
callback: (...args: unknown[]) => void,
18-
) => google.maps.MapsEventListener | undefined;
17+
callback: (args: T) => void,
18+
): google.maps.MapsEventListener | undefined;
1919
}
2020
| undefined;
2121

@@ -48,8 +48,8 @@ export class MapEventManager {
4848
return undefined;
4949
}
5050

51-
const listener = target.addListener(name, (event: unknown) => {
52-
this._ngZone.run(() => observer.next(event as T));
51+
const listener = target.addListener(name, (event: T) => {
52+
this._ngZone.run(() => observer.next(event));
5353
});
5454

5555
// If there's an error when initializing the Maps API (e.g. a wrong API key), it will

Diff for: src/universal-app/hydration.e2e.spec.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import {browser, by, element, ExpectedConditions} from 'protractor';
22

3-
// Expect `ngDevMode` to be always set:
4-
declare const ngDevMode: {
5-
hydratedComponents: number;
6-
componentsSkippedHydration: number;
7-
};
3+
declare global {
4+
interface Window {
5+
ngDevMode: {
6+
hydratedComponents: number;
7+
componentsSkippedHydration: number;
8+
};
9+
}
10+
}
811

912
describe('hydration e2e', () => {
1013
beforeEach(async () => {
@@ -33,7 +36,7 @@ async function getHydrationState() {
3336
hydratedComponents: number;
3437
componentsSkippedHydration: number;
3538
}>(() => ({
36-
hydratedComponents: ngDevMode.hydratedComponents,
37-
componentsSkippedHydration: ngDevMode.componentsSkippedHydration,
39+
hydratedComponents: window.ngDevMode.hydratedComponents,
40+
componentsSkippedHydration: window.ngDevMode.componentsSkippedHydration,
3841
}));
3942
}

Diff for: src/universal-app/kitchen-sink/kitchen-sink.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ interface ElementItem {
6969
}
7070

7171
export class TableDataSource extends DataSource<ElementItem> {
72-
connect(): Observable<Array<ElementItem>> {
72+
connect(): Observable<ElementItem[]> {
7373
return observableOf([
7474
{position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
7575
{position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
@@ -84,7 +84,7 @@ export class TableDataSource extends DataSource<ElementItem> {
8484
]);
8585
}
8686

87-
override disconnect() {}
87+
disconnect() {}
8888
}
8989

9090
export const AUTOMATED_KITCHEN_SINK = new InjectionToken<boolean>('AUTOMATED_KITCHEN_SINK');

Diff for: src/youtube-player/fake-youtube-player.ts

+21-17
Original file line numberDiff line numberDiff line change
@@ -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+
3338
export 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

Comments
 (0)