[SOLVED] TypeScript interface that allows other properties


In summary, is it possible to have an interface that declares some base properties, but does not restrict additional properties? This is my current situation:

I’m using the Flux pattern, which defines a generic dispatcher:

class Dispatcher<TPayload> {
    dispatch(arg:TPayload):void { }

I then create a dispatcher with my own payload type, like this:

interface ActionPayload {
    actionType: string

const dispatcher = new Dispatcher<ActionPayload>();

Now I have some action code that should dispatch a payload with some additional data, but the ActionPayload interface only allows for actionType. In other words, this code:

interface SomePayload extends ActionPayload {
    someOtherData: any

class SomeActions {
    doSomething():void {
            actionType: "hello",
            someOtherData: {}

Gives a compile-error because someOtherData does not match the ActionPayload interface. The issue is that many different “action” classes will re-use the same dispatcher, so while it’s someOtherData here it might be anotherKindOfData over there, and so on. At the moment, all I can do to accomodate this is use new Dispatcher<any>() because different actions will be dispatched. All actions share a base ActionPayload, though, so I was hoping to be able to constrain the type like new Dispatcher<extends ActionPayload>() or something. Is something like that possible?


If you want ActionPayload to accept any other property you can add an indexer:

interface ActionPayload {
    actionType: string;

    // Keys can be strings, numbers, or symbols.
    // If you know it to be strings only, you can also restrict it to that.
    // For the value you can use any or unknown, 
    // with unknown being the more defensive approach.
    [x: string | number | symbol]: unknown;

See https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#strict-object-literal-assignment-checking

Answered By – Sebastien

Answer Checked By – Jay B. (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *