Below is the class I've created to capture the console.log
function in my application. This allows me to review logs on devices where accessing the browser console isn't easy, and also helps in bundling captured logs for error reporting later on.
To make it work, I had to include ts-ignore
as shown below:
// @ts-ignore
oldDebug.apply(console, arguments);
If I remove the ts-ignore
directive, I encounter the following error:
Argument of type 'IArguments' is not assignable to parameter of type '[any?, ...any[]]'.
Here's the code snippet used for capturing the logs:
let oldLog: typeof console.log;
export type LogLevel = "log"|"debug"|"warn"|"error";
export interface ConsoleLogMessage {
level: LogLevel,
arguments: IArguments,
}
export function interceptConsoleLogs() {
if (oldLog) {
throw new Error("Log functions already intercepted");
}
oldLog = console.log;
window.console.log = function() {
storeLogMessage("log", arguments);
// @ts-ignore
oldLog.apply(console, arguments);
};
// debug, warn, error...
}
export function getCurrentLogMessages(): ConsoleLogMessage[] {
return logStorage.slice(0);
}
const maxLogs = 100;
const logStorage: ConsoleLogMessage[] = [];
function storeLogMessage(level: LogLevel, args: IArguments) {
if (logStorage.length >= maxLogs) {
logStorage.shift();
}
logStorage.push({level: level, arguments: args});
}
How should the types be structured to perform these apply
calls without needing to add ts-ignore
?
Environment:
My application is a create-react-app
project upgraded to TypeScript 3.6.3, with the following tsconfig.json
:
{
"compilerOptions": {
"baseUrl": "src",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve"
},
"include": [
"src"
]
}