Home > database >  What is the <any> doing in the following code?
What is the <any> doing in the following code?

Time:11-23

export namespace MyNameSpace {
           ...
    ... much stuff ...
           ...
    [
        'item1',
        'item2'
    ].forEach(x=>{
        (<any>MyNameSpace)[x] = function (r,s,o) {
            return someFunction(x,r,s,o);
        };
    });
}

original version:

[
    'item1',
    'item2'
].forEach(x=>{
    (<any>MyType)[x] = function (r,s,o) {
        return someFunction(x,r,s,o);
    };
});

No search engine (even Stack Overflow or GitHub) returns any useful results searching for <any>.

CodePudding user response:

Your code has potential bugs, a great feature of TypeScript is the fact that you can avoid generic types, so use interfaces! (<any> is a generic type).

In your example code, <any> means that MyNameSpace is being cast to an object of unknown attributes, which means that anything you pass to x would be "valid".

Your code is kind of equivalent to this:

MyNameSpace.item1 = function(...) { return ...}
MyNameSpace.item2 = function(...) { return ...}

Normally that code would return errors when item1 and item2 are not part of MyNameSpace definition, that being said... the <any> cast is being used to avoid that error. Is an antipattern.

One way to address this kind of need is to add the new attributes to the MyNameSpace definition and then add a line of code for every attribute:

export interface MyType {  // <-- example interface for 'MyNameSpace' object
    item1: () => {};
    item2: () => {};
}
MyNameSpace.item1 = function(...) { return ...}
MyNameSpace.item2 = function(...) { return ...}

This has the inconvenience of adding a line of code for every attribute, however, it'll save you a lot of refactoring issues in the future.

As stated by @VLAZ in comments, another way to address your requirement is to use an indexed type, which might be easier to maintain:

export enum availableItems {
    item1 = 'item1',
    item2 = 'item2',
    ...
}

export type MyType = {
    [itemKey in availableItems]: () => {}
}

// ...later you can iterate `availableItems ` enum definition which will be valid attributes

In a simple statement, whenever possible avoid using the generic type <any>. In my case, it's a burden I've always regretted doing.

  • Related