danikaze
danikaze

Reputation: 1654

Typescript mapped interfaces

I have this interface:

interface Events {
  SERVER_START: {
    version: string;
  };
  SERVER_READY: {
    host: string;
    port: number;
  };
  SERVER_STOP: undefined;
  SERVER_STOP_ERROR: {
    error: Error;
  };
  SERVER_CONNECTION_INCOMING: {
    clientId: string;
    address: string;
    port: number;
  };
 ...
}

is it possible to map functions parameters like this?

function logEvent(type: keyof Events, data?: Events[keyof Events]): void;

This work almost fine, since I can call logEvent like this:

// this is correct:
logEvent('SERVER_START', { version: '0.1.0' });

// but this is also correct, which shouldn't
logEvent('SERVER_START');
logEvent('SERVER_START', { host, port });

Of course, intellisense also don't work as expected so, I had to manually define all the overloadings of the function like...

function logEvent(type: 'SERVER_START', data: Events['SERVER_START']): void;
function logEvent(type: 'SERVER_READY', data: Events['SERVER_READY']): void;
function logEvent(type: 'SERVER_STOP'): void;
...

which works like a charm, but it looks to me like there should be a better way to define all of this automagically...

Update:

So, the idea is not having only Events but extending that interface with other definitions as well, so the idea would be to have a generic function like

function logEvent<E extends Events>(type: keyof E, data?: E[keyof E]): void;

so you can actually do

interface MoreEvents extends Events {
  FOOBAR: {
    foo: string;
    bar: number;
  };
}

// call it with the original ones
logEvent('SERVER_START', { version: '0.1.0' });

// call it also with the new events
logEvent<MoreEvents>('FOOBAR', { foo, bar });

but with proper type checking

Upvotes: 0

Views: 49

Answers (1)

ThomasThiebaud
ThomasThiebaud

Reputation: 11969

You can redefine your logEvent function using generics

logEvent<E extends Events>(type: keyof E, data?: E[keyof E]): void;

Update

This solution works with the updated question. Check that playground

Upvotes: 1

Related Questions