If you need to inject the window because you do really need properties belonging to the "window", just create a service as follow
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class WindowService {
public getInstance(): Window {
return window;
}
}
Here is an example where it becomes easy to mock WindowService
for testing purpose:
export class AnotherService {
constructor(private windowService: WindowService) {}
public hasPreviousPage(): boolean {
return this.windowService.getInstance().history.length > 2;
}
}
If however you are using window to then get a globally defined variable, I would recommend at first using globalThis instead. Then, typing the global is a matter of typescript module, in short: Do something like this:
Declare this ambient context this somewhere
declare global {
function hello():string;
}
Then ts won't complain for the following code:
globalThis.hello(); // best way
window.hello(); // okay but window could be undefined in tests, workers or headless nodejs
Note that you still need to add the implementation of hello()
globally somewhere.
Of course you could also (but I DO NOT recommend) use the following dirty trick:
import { Injectable } from '@angular/core';
interface ExtraParams {
hello:() => string;
}
@Injectable({
providedIn: 'root',
})
export class WindowService {
public getInstance(): Window & ExtraParams {
return window as unknown as Window & ExtraParams;
}
}