Wayne Barnard
Wayne Barnard

Reputation: 174

Typescript Index Signature and methods in the implementing class doesn't work

I`m trying to create my own Typescript dictionary like class, but with some custom methods to use in my code.

I can create the basic dictionary like this:

export interface IDictionary<T> {
 [property: string]: T;
};

export class Dictionary<T> implements IDictionary<T> {
 [property: string]: T;
 constructor() {}
}

and this works great...but... if i try to create a method in this class, such as

export class Dictionary<T> implements IDictionary<T> {
 [property: string]: T;
 constructor() {}

 public getValues(): T[] { // this will give the error
    return Object.values(this);
 }
}  

I get this error:

Property 'getValues' of type '() => T[]' is not assignable to string index type 'T'.

Is this even possible? If it is, how can I create methods for my class?

Upvotes: 4

Views: 1037

Answers (1)

Kevin M
Kevin M

Reputation: 317

Encountered a very similar thing when getting into TypeScript. Just adding a function to a class broke things, nevermind actually calling the function.

The 'problem' seemed to arise from the fact that you can essentially use a class as an interface. In your example, you'd be able to do something like the following without a problem.

let myobject: Dictionary<string>;
myobject = {'name': 'John'};

But notice while you'd be declaring the object to be of type Dictionary it's not actually an instance of the Dictionary class, but just a regular javascript object.

Adding any method to the Dictionary class would result in the original error.

Our solution was to be mindful of when you have an object that conforms to an interface, and when you have an instance of a class. My above example should really be...

let myobject: IDictionary<string>;
myobject = {'name': 'John'};

If I wanted to say add a method to the Dictionary class and use it, I would need a Dictionary object

let myobject: IDictionary<string>;
myobject = {'name': 'John'};

let myinstance: Dictionary<string>;
myinstance = new Dictionary(myobject);
myinstance.getValues();

So back to your original question, I would guess you're declaring something of type Dictionary when it should really be of type IDictionary?

Also, if anyone has information/documentation/references on using a class as an interface or I'm grossly wrong on that topic, let me know!

Upvotes: 3

Related Questions