need some help with implementing interfaces

Topics: General
Oct 7, 2012 at 5:25 PM

How would a TypeScript class look like that implements the following interface:

interface HTMLCollection {   
   length: number;   
   item(nameOrIndex?: any, optionalIndex?: any): Element;   
   (nameOrIndex: any, optionalIndex: any): Element;   
   namedItem(name: string): Element;   
   [index: number]: Element;   
   [name: string]: Element;   
   (name: string): Element;
}

I do understand what the different method signatures mean, just having a hard time implementing a class/function that successfully implements the above interface.

Can anyone show a short code snippet that does the trick? 

Coordinator
Oct 8, 2012 at 5:11 PM

Not all interfaces are meant to be implemented with classes.  Some, like those with an indexing member, are meant to be used as a type annotation on JavaScript code that adds members to an array.

Hope that helps.

Oct 8, 2012 at 5:34 PM

I understand the meaning of the signatures (so some of them are indexed accessor and some even function calls). So I understand the implementation is not always a class. However if a method is guaranteed to return the above interface, how could I make the compiler happy. 

Or are you saying it is impossible to implement the above interface in a single return type?

Oct 8, 2012 at 6:01 PM

Keep in mind that TypeScript is really just a thin layer over the top of JavaScript so you can't do anything in TypeScript that you can't also do in JavaScript.  So you can't create functions that implement things like indexers because JavaScript doesn't let you do that.  You can use indexers to access arrays and object literals in JavaScript so TYpeScript lets you express that via an interface but they're not things you can actually implement via a class.

Coordinator
Oct 8, 2012 at 6:20 PM

Sometimes the interface is meant to be over code that you may or may not have written the implementation for, more like a C header on a library.  Not all interfaces that you could write will make sense, per se.

You can create a return type from your above example like this:

interface HTMLCollection {   
   item(nameOrIndex?: any, optionalIndex?: any): Element;    
   (nameOrIndex: any, optionalIndex: any): Element;    
   namedItem(name: string): Element;    
   [index: number]: Element;    
   [name: string]: Element;    
   (name: string): Element;
}

function foo(x): HTMLCollection { return <HTMLCollection><any>[]; }
Oct 8, 2012 at 6:31 PM

Thanks for the example, that is similar to the approach I decided to take when I couldn't figure it out.

P.S. I guess with es6 proxies it would be actually possible to create an object that would response to the following messages (this is my understanding of the above interface description):

x.item(2)

x(2)

x.namedItem("abc")

x[2]

x["abc"]

x("abc")