JWP
JWP

Reputation: 6963

How do I get Visual Studio Intellisense to reveal the properties in javascript call back?

export class Helper { 
static forEach(array, callback) {
    jQuery.each<string>(array, (index) => {
        var item = callback({Item: array[index], Continue: true });
        return item.Continue;
    });
}
//how do I get item to Not be type of any?
static Test() {
    var array = [1, 2, 3, 4, 5];
    this.forEach(array, item => {          
      item.  <---  No Intellisense prompt for Item or Continue here.
    });
  }
}

I'm creating a helper class which contains a callback, as you can see in the callback, it is sending an object with two properties. The Test function shows how it's used and what I'd like it to do.

I've tried definining a class and passing it instead, still Intellisense just cannot pick up on the type.

export class ItemContinue {
    constructor(item) {
        this.Item = item;
    }
    Item: any = null;
    Continue: boolean = true;
}

export class Helper { 
static forEach(array, callback) {
    jQuery.each<string>(array, (index) => {
        var item = New ItemContinue(array[index]);
        callback(item);
        return item.Continue;
    });
}

Upvotes: 0

Views: 181

Answers (1)

Rich Seviora
Rich Seviora

Reputation: 1809

The problem is that the callback parameter on Helper.forEach doesn't have a type assignment. Therefore it is implicitly treated as any. That also means it can't provide you with any completions because any can have all properties and none.

Compare your code above with this:

static forEachTyped<T>(array : T[], callback : ({Item: T, Continue: boolean}) =>  {Item: T, Continue: boolean})
{
    jQuery.each<string>(array, (index) => {
        var item = callback({ Item: array[index], Continue: true });
        return item.Continue;
    });        
}    

Here, I've given the callback parameter a type of ({Item: T, Continue: boolean}) => {Item : T, Continue : boolean}. This is the signature for a function that takes an single argument of type {Item: T, Continue: boolean} and returns the a value of type {Item: T, Continue: boolean}.

Because you've now assigned a type to the callback function parameter, Intellisense for this function now operates:

static Test3() {
    var array = [1,2,3,4,5];
    this.forEachTyped<number>(array, (item) => {
        item. // Should provide completion for Continue and Item properties.
        return {Continue: item.Continue, Item: item.Item};
    })
}  

To avoid similar problems you can set noImplicitAny in your tsconfig.json to true. This will generate errors whenever your code would assign an implicit any type and force you to assign a type to the value in question.

Upvotes: 1

Related Questions