8

I'm trying to do an extension of one of my interfaces, but keep getting the error "index signature is missing in type {dcs: Relationship} with the following snippet:

interface Relationship {
    data: {
        id: string;
        type: string;
    }
}

interface T {
    relationships: {[key: string]: Relationship};
}

interface Test extends T {
    relationships: {
        dcs: Relationship;
    };
}

The goal is for the relationships property in T to be an object with any number of keys that are all of the Relationship type. Test is supposed to be a specific implementation of type T.

Not sure what the correct way to approach this is. Thanks in advance!

2 Answers2

2

Declare Test like so:

interface Test extends T {
  relationships: {
    [key: string]: Relationship;
    dcs: Relationship;
  };
}

However, as you've noticed you end up having to declare the indexer again when you actually implement the interface. You could save some typing by doing this:

interface T {
  relationships: {
    [key: string]: Relationship;
  };
}

interface TestRelationships {
   [key: string]: Relationship;
   dcs: Relationship;
}

interface Test extends T {
  relationships: TestRelationships;
}

class T1 implements Test {
  relationships: TestRelationships;
}
Vadim Macagon
  • 14,463
  • 2
  • 52
  • 45
  • Thanks! I get the same issue though when I try and implement it in a class :/ `class T1 implements Test { relationships = { dcs: { data: { id: "test", type: "test" } } } }` – Alexander Mattoni Jan 24 '16 at 00:16
1

A solution too if the type doesn't need to be an interface! Is to use an object literal type

(( However adding the index signature to the interface can be a better option )) It's to show that we can do that too!

ex:

export type SignalProcessorEvents =  {
    valueCandle: (
        value: WhalesCandle,
        storageType: StorageType | undefined
    ) => void
}

Illustration:

When using the interface (typescript complaining)

enter image description here

When switching to object literal

enter image description here

Extension code for the one that want to see it:

export class Events<EventsObject extends { [eventName: string]: (...args: any[]) => void}> {
    protected _events: EventsObject = {} as any;

Mohamed Allal
  • 17,920
  • 5
  • 94
  • 97