6

I had the following javascript in my error logging code, which defines console.log for certain browsers where it doesn't exist (IE doesn't/didn't have it defined unless the debug tools are open).

if (typeof console == "undefined")
{
    window.console = { log: function (msg) { } };
}

The problem when trying to upgrade the js to Typescript is that window.console is defined as being of the Console interface type and since I'm not specifying everything it (obviously) doesn't compile.

interface Console {
    info(message?: any, ...optionalParams: any[]): void;
    profile(reportName?: string): void;
    assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
    msIsIndependentlyComposed(element: Element): boolean;
    clear(): void;
    dir(value?: any, ...optionalParams: any[]): void;
    warn(message?: any, ...optionalParams: any[]): void;
    error(message?: any, ...optionalParams: any[]): void;
    log(message?: any, ...optionalParams: any[]): void;
    profileEnd(): void;
}

How can tell it to ignore this interface and just let me redefine window.console.

My best effort guess doesn't work

window.console = { log: function (msg) { } } : any;
Community
  • 1
  • 1
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689

3 Answers3

5

A shorter solution is to just use a type assertion:

window.console = <any>{ log: function (msg) { } };

And even use a lambda:

window.console = <any>{ log: () => { } };
basarat
  • 261,912
  • 58
  • 460
  • 511
  • thanks :-) I wish the language spec has said something like 'this is the most similar feature to casting' so I could have found this – Simon_Weaver May 23 '14 at 08:22
  • 2
    Yeah. They used a different term because casting implies runtime support. I.e. actual conversion. Saying it is similar to casting would make people think that e.g it actually converts a string to a number. With assertion you are only asserting that you know better than the compiler inference – basarat May 23 '14 at 09:17
  • 2
    `console` is now a `readonly` property as of typescript 2 - so you have to do this instead `(window).console = { log: () => { } };` – Simon_Weaver Nov 03 '16 at 04:08
  • 2
    curious if you have any opinion on `console` now being readonly. seems a bit weird to me - especially considering there are legitimate reasons for needing to set it. I suppose it helps beginners with silly mistakes but I think it's an oversight – Simon_Weaver Nov 03 '16 at 04:09
4

The interface is going to force you to create all functions. If you try to override the interface, it will give you a Duplicate Identifier error. So, here's the full stub to save you time :)

window.console =
{
    info: (message?: any, ...optionalParams: any[]) =>
    {
        // ...
    },

    profile: (reportName?: string) =>
    {
        // ...
    },

    assert: (test?: boolean, message?: string, ...optionalParams: any[]) =>
    {
        // ...
    },

    msIsIndependentlyComposed: (element: Element) =>
    {
         return false;
    },

    clear: () =>
    {
        // ...
    },

    dir: (value?: any, ...optionalParams: any[]) =>
    {
        // ...
    },

    warn: (message?: any, ...optionalParams: any[]) =>
    {
        // ...
    },

    error: (message?: any, ...optionalParams: any[]) =>
    {
        // ...
    },

    log: (message?: any, ...optionalParams: any[]) =>
    {
        // ...
    },

    profileEnd: () => 
    {
        // ...
    },

    count: (countTitle?: string) => 
    {
        // ...
    },

    groupEnd: () => 
    {
        // ...
    },

    time: (timerName?: string) => 
    {
        // ...
    },

    timeEnd: (timerName?: string) =>
    {
        // ...
    },

    trace: () => 
    {
        // ...
    },

    group: (groupTitle?: string) => 
    {
        // ...
    },

    dirxml: (value: any) => 
    {
        // ...
    },

    debug: (message?: string, ...optionalParams: any[]) => 
    {
        // ...
    },

    groupCollapsed: (groupTitle?: string) => 
    {
        // ...
    },

    select: (element: Element) => 
    {
        // ...
    },
};

Alternate Solution

If you don't want to write out all methods, you can fool TypeScript like this.

var x: any = 
{
    log: (msg) =>
    {
        //...
    }
};
window.console = <Console>x;
Laith
  • 6,071
  • 1
  • 33
  • 60
1

I suppose I could do this :-/

 var w:any = window;
 w.console = { log: function (msg) { } };
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689