Home > Net >  How to extend an interface and pick all fields from another one?
How to extend an interface and pick all fields from another one?

Time:08-06

Given the following interface

interface MyCustomInterface {
    aField: string;
}

and a library providing the following

type CommandData = Record<string, unknown>;

class Command<TData extends CommandData> {}

When creating a custom command I could go for

interface CustomCommandData extends CommandData {
    aField: string;
}

class CustomCommand extends Command<CustomCommandData> {}

But there is no need for CustomCommandData because I could simply use MyCustomInterface instead. E.g.

class CustomCommand extends Command<MyCustomInterface> {}

The compiler tells me that's not possible because

TS2344: Type 'MyCustomInterface' does not satisfy the constraint 'CommandData'.   Index signature for type 'string' is missing in type 'MyCustomInterface'.

How can I modify CustomCommandData to

  • pick all fields from MyCustomInterface
  • extend CommandData

? I'm basically looking for something like

interface CustomCommandData extends CommandData where this extends MyCustomInterface {}

CodePudding user response:

You can use an intersection type for this.

type CustomCommandData = CommandData & MyCustomInterface;

This creates a type that is assignable to both CommandData and MyCustomInterface.

Side note

If you're in control of the library that defines CommandData, there's options for that type which would prevent this kind of issue. If CommandData was defined to be Record<string, any> instead, MyCustomInterface would be assignable out of the box, while still preserving the limitation to only using "object types" due to the usage of Record.

  • Related