使用 TypeScript 和 EventEmitter 的类型化事件
Typed events with TypeScript and EventEmitter
我正在尝试使用 TypeScript 将强类型事件添加到类似 EventEmitter 的系统。
目前,我们定义类型如下:
interface TypedMsg<Name, T> {
messageType: Name;
message: T;
}
type TypedMsgFoo = TypedMsg<'FOO', string>;
type TypedMsgBar = TypedMsg<'BAR', number>;
type EitherFooOrBar = TypedMsgFoo | TypedMsgBar;
我想定义一个接口:
interface EventHandler<T extends TypedMsg<any, any> {
on: (messageType: T.messageType, handler: (T.message) => void) => void;
}
但 Typescript 不支持像 T.messageType
那样提取子类型。还有其他方法吗?
最终目标是通过以下方式定义具有正确类型的处理程序:
class FooBarHandler implements EventHandler<EitherFooOrBar> {
on(messageType: EitherFooOrBar.messageType) {...}
}
Typescript 确实支持提取成员类型,只是语法有点不寻常 - 它叫做 indexed access type operator
interface TypedMsg<Name, T> {
messageType: Name;
message: T;
}
type TypedMsgFoo = TypedMsg<'FOO', string>;
type TypedMsgBar = TypedMsg<'BAR', number>;
type EitherFooOrBar = TypedMsgFoo | TypedMsgBar;
interface EventHandler<T extends TypedMsg<{}, {}>> {
on: (messageType: T['messageType'], handler: (m: T['message']) => void) => void;
}
class FooBarHandler implements EventHandler<EitherFooOrBar> {
on(
messageType: EitherFooOrBar['messageType'],
handler: (m: EitherFooOrBar['message']) => void
) {
}
}
然而,输入所有这些明确说明类型的声明很快就会变得非常乏味 - 你会想要设计一些允许打字稿为你推断类型的东西,例如像这个问题:
我正在尝试使用 TypeScript 将强类型事件添加到类似 EventEmitter 的系统。
目前,我们定义类型如下:
interface TypedMsg<Name, T> {
messageType: Name;
message: T;
}
type TypedMsgFoo = TypedMsg<'FOO', string>;
type TypedMsgBar = TypedMsg<'BAR', number>;
type EitherFooOrBar = TypedMsgFoo | TypedMsgBar;
我想定义一个接口:
interface EventHandler<T extends TypedMsg<any, any> {
on: (messageType: T.messageType, handler: (T.message) => void) => void;
}
但 Typescript 不支持像 T.messageType
那样提取子类型。还有其他方法吗?
最终目标是通过以下方式定义具有正确类型的处理程序:
class FooBarHandler implements EventHandler<EitherFooOrBar> {
on(messageType: EitherFooOrBar.messageType) {...}
}
Typescript 确实支持提取成员类型,只是语法有点不寻常 - 它叫做 indexed access type operator
interface TypedMsg<Name, T> {
messageType: Name;
message: T;
}
type TypedMsgFoo = TypedMsg<'FOO', string>;
type TypedMsgBar = TypedMsg<'BAR', number>;
type EitherFooOrBar = TypedMsgFoo | TypedMsgBar;
interface EventHandler<T extends TypedMsg<{}, {}>> {
on: (messageType: T['messageType'], handler: (m: T['message']) => void) => void;
}
class FooBarHandler implements EventHandler<EitherFooOrBar> {
on(
messageType: EitherFooOrBar['messageType'],
handler: (m: EitherFooOrBar['message']) => void
) {
}
}
然而,输入所有这些明确说明类型的声明很快就会变得非常乏味 - 你会想要设计一些允许打字稿为你推断类型的东西,例如像这个问题: