0

Imagine we have interface below:

interface Interface1 {
    [index: string]: string;
    param1: string;
}

And we would like to implement above interface; also we want to add another field with the type of number to the class fields:

class MyClass implements Interface1 {
    [index: string]: string;
    param1: string;
    param2: number; // TS2411 error
}

But we get an error, as our param2 type does not match the type of the index signature, so instead I tried to change index signature (I was expecting it to not solve the problem):

class MyClass implements Interface1 { // TS2420
    [index: string]: string | number; 
    param1: string;
    param2: number;
}

So, my question is how do you implement interface (without modifying it) with index signature and add another field with different type in class?

interface SomeInterface {
  param: string;
}

class SomeClass implements SomeInterface {
  param: string;
  num: number;
}

How do you do same for interface that has index signature?

109149
  • 1,223
  • 1
  • 8
  • 24
  • That's a typescript constriction, your index signature MUST be a union of all possible field value types. there is simply no way around it. Instead i would suggest to think about Composition Over Inheritance – Marian Theisen Dec 14 '20 at 13:40
  • I understand why it should be union, but what I am curious about is how do you add new fields in class without modifying interface. – 109149 Dec 14 '20 at 14:14
  • instead of thinking in class and interface, ask yourself: is `{something: number | string}` (==class) assignable to `{something: string}` (==interface) and the answer is obviously no. So what you are trying to do is not possible in a type safe way – Marian Theisen Dec 14 '20 at 14:34

1 Answers1

0

Does it work for you ? :

interface Interface1 {
    [index: string]: string | number;
}

class MyClass implements Interface1 {
    [index: string]: string | number;
    param1: string;
    param2: number;

    constructor(public param1: string, public param2: number) {
        this.param1 = param1
        this.param2 = param2
    }
}