Categories
Development

How to correctly type the apply method for browser console logging functions?

I’ve written the below class to capture the console.log function in my app so I can review the logs on devices where I can’t easily access the browser console and so later I can bundle the captured logs when reporting errors.

In order to get it working, I’ve had to add ts-ignore like this:

// @ts-ignore
oldDebug.apply(console, arguments);

Without the ts-ignore directive, I get the following error:

Argument of type 'IArguments' is not assignable to parameter of type '[any?, ...any[]]'. 

Here is the code I’m using 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 my types look if I want to do these apply calls without adding ts-ignore?


Environment:
My app 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"
  ]
}

Leave a Reply

Your email address will not be published. Required fields are marked *