Типизированные события с помощью TypeScript и EventEmitter

Я пытаюсь добавить строго типизированные события в систему, подобную EventEmitter, используя TypeScript.

В настоящее время мы определяем наши типы следующим образом:

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) {...}
}

person KurtPreston    schedule 09.05.2017    source источник
comment
Этот ответ должен вам помочь.   -  person aleclarson    schedule 15.09.2018


Ответы (1)


Typescript поддерживает извлечение типов членов, просто синтаксис немного необычен — он называется оператор индексированного типа доступа

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

person artem    schedule 09.05.2017