Reputation: 1654
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
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