When running in a browser, window.console may be unavailable while the browser's developer tools are not opened. Calls to window.console may therefore cause errors. To circumvent this, a common approach is to assign a dummy class with the required methods to catch this situation. However, after the introduction of the readonly modifier, this approach no longer works, and instead produces a compiler error.
TypeScript Version: 2.1.1 / nightly (2.2.0-dev.201xxxxx)
Code
if (typeof window.console === "undefined") {
// Define a dummy window.console if not debugging
window.console = <Console>({
debug: (message ?: string, ...optionalParams: any[]) => {},
error: (message?: any, ...optionalParams: any[]) => {},
info: (message ?: any, ...optionalParams: any[]) => {},
log: (message?: any, ...optionalParams: any[]) => {},
warn: (message?: any, ...optionalParams: any[]) => {}
});
}
Expected behavior:
window.console is set to the dummy class when the console is not available and uses the browser's console otherwise
Actual behavior:
TS2540: Cannot assign to 'console' because it is a constant or a read-only property.
Try this
declare global {
interface Window {
console: Console;
}
}
@aluanhaddad I assume your suggestion should go into my .ts file? If that's so, then unfortunately, your solution doesn't work, as I get
TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
in addition to the previous error.
console is a readonly property of Window. Try casting window to any. This erases all type info, so it should be allowed.
if (typeof window.console === "undefined") {
// Define a dummy window.console if not debugging
(<any>window).console = <Console>({
debug: (message ?: string, ...optionalParams: any[]) => {},
error: (message?: any, ...optionalParams: any[]) => {},
info: (message ?: any, ...optionalParams: any[]) => {},
log: (message?: any, ...optionalParams: any[]) => {},
warn: (message?: any, ...optionalParams: any[]) => {}
});
}
@alitaheri That does the trick. Thank you.
@aluanhaddad I assume your suggestion should go into my .ts file? If that's so, then unfortunately, your solution doesn't work, as I get
TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
in addition to the previous error.
My approach presumed that you were using external modules, for which I apologize. You can use
interface Window {
console: Console;
}
instead.
That said, if you otherwise want to preserve the readonlyness of window.console then @alitaheri's solution is the way to go.
Most helpful comment
consoleis a readonly property ofWindow. Try casting window toany. This erases all type info, so it should be allowed.