'Extend index signature of interface

I'm trying to extend an interface which has an index signature. However, when adding new properties that have different type, the old index signature leads to an error. Is it possible to redefine the old index signature?

interface A {
  a: number;
  b: string;
  [key: string]: number | string;
}

interface B extends A {
  c: Function;
}

Error: Property 'c' of type 'Function' is not assignable to string index type 'string | number'.ts(2411)



Solution 1:[1]

If B extends A, it means that B must be usable in places where A is accepted.

By 'widening' the definition, not every instance of B is compatible with A, so this is not allowed.

Usually the key to solving these types of issues is by trying to avoid the index signature. It's often over-used and almost as bad as any

Solution 2:[2]

In A you made a rule on your keys so B have to respect it

Solution 3:[3]

Use type aliases.

type B = A & {
  c: Function;
};

Solution 4:[4]

As far as I know, there's no way to override the index signature if you're using an interface. You could use a type alias and intersection instead since types aliases allow properties to be overridden.

You also need to turn on --strictFunctionTypes check for typescript in order to make it work.

interface A {
  a: number;
  b: string;
  [key: string]: number | string;
}

type B = A & {
  c: Function;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Evert
Solution 2 FrV
Solution 3 12kb
Solution 4