Typescript 类型脚本映射接口
我有这个界面:Typescript 类型脚本映射接口,typescript,Typescript,我有这个界面: interface Events { SERVER_START: { version: string; }; SERVER_READY: { host: string; port: number; }; SERVER_STOP: undefined; SERVER_STOP_ERROR: { error: Error; }; SERVER_CONNECTION_INCOMING: { clientId: st
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;
};
...
}
可以这样映射函数参数吗
function logEvent(type: keyof Events, data?: Events[keyof Events]): void;
这项工作几乎很好,因为我可以这样调用logEvent:
// 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 });
当然,intellisense也不能像预期的那样工作,所以,我必须手动定义函数的所有重载,如
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;
...
这就像一个魅力,但在我看来,应该有一个更好的方式来定义所有这些自动
更新:
因此,我们的想法不仅仅是拥有事件,而是通过其他定义扩展该接口,因此我们的想法是拥有一个通用函数,如
function logEvent<E extends Events>(type: keyof E, data?: E[keyof E]): void;
所以你可以做到
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 });
但是通过适当的类型检查,您可以使用泛型重新定义logEvent函数
logEvent<E extends Events>(type: keyof E, data?: E[keyof E]): void;
更新
此解决方案适用于更新的问题。检查omg如此愚蠢的解决方案。。。我尝试了很多,但没有得到正确的语法。谢谢,这很有效。顺便说一下,将第二个参数设置为可选也很好:乐意帮忙。我不确定第二个参数,等等,如果T扩展了事件的范围,这意味着,可能有一些值,这些值将是未定义的,对吗?所以这不是真的有效…要回答您的评论,如果您有logEvent,那么T将始终是事件的关键之一,因此没有undefinedIt也适用于更新的问题,请检查更新答案中的游乐场