Как стать автором
Обновить

Комментарии 9

Что думаете по поводу условного workaround решения как подход к устранению таких базовых ограничений

1. Создаем файл lib_extends.dom.d.ts
/** Первый вариант */
interface CustomMessageEvent<T = any> extends MessageEvent {
    data: T;
}
interface Worker {
    addEventListener<T>(message: string, handler: (message: CustomMessageEvent<T>) => any, options?: boolean | AddEventListenerOptions): any;
}

/** Второй вариант */
interface Worker {
    addEventListener<T = any>(message: string, handler: (message: Omit<MessageEvent, "data"> & {data: T}) => any, options?: boolean | AddEventListenerOptions): any;
}

2. Добавляем в tsconfig.json в секцию include строку
    "include": [
        "./путо до lib_extends.dom.d.ts",
    ]

3. И далее в коде проекта используем
const worker = new Worker(...);

worker.addEventListener<string>("message", (message => {
    message.data // (property) data: string
}))

В моих проектах используется такой подход:


// globals.d.ts

interface TypedMessageEvent<T> extends MessageEvent {
    data: T;
}

interface TypedWorkerEventMap<T, E = T> extends AbstractWorkerEventMap {
    "message": TypedMessageEvent<T>;
    "messageerror": TypedMessageEvent<E>;
}

interface TypedWorker<Input, Output> extends Worker {

    postMessage(message: Input, transfer: Transferable[]): void;

    postMessage(message: Input, options?: PostMessageOptions): void;

    addEventListener<K extends keyof TypedWorkerEventMap<Output>>
    (type: K, listener: (this: TypedWorker<Input, Output>, ev: TypedWorkerEventMap<Output>[K]) => any, options?: boolean | AddEventListenerOptions): void;
}

Это позволяет описать как все входящие так и исходящие сообщения


type MessageStart = 'start';
type MessageStop = 'stop';
type MessageProgress = 'progress'

type MessageInput = MessageStart | MessageStop
type MessageOutput = MessageProgress

const w = new Worker() as TypedWorker<MessageInput, MessageOutput>

w.addEventListener('message', m => {
  m.data // 'start' | 'stop'
})

w.postMessage('some') // Type "some" is not assignable to type "MessageProgress"

Мне всегда было интересно, а в чем преимущество генерации кода из json перед непосредственно кодом как есть?

Не совсем понял ваш вопрос

Почему просто не хранится файл src/lib/d.ts в котором можно просто напрямую поменять код? Зачем вносить изменения в JSON из которых код сгенерируется?
Ну, то есть я понимаю, что раз так делают, в этом есть какое-то преимущество, вот мне и интересно какое.

Если коротко — для автоматизеции и уменьшения ручной работы.


Если чуть подробнее:


  1. Источником всех типов являются .widl файлы. Они автоматически вытягиваются из браузера Edge. То есть, все веб интерфейсы пишутся не вручную а берутся из того, что имплементировано в браузере. Вот, описание MessageEvent, например.
    Так можно быстро и легко отслеживать все изменения в спецификациях веб-платформы.
  2. Многие такие интерфейсы должны быть представлены в нескольких библиотеках. Чтобы не приходилось согласовывать описание одного и того же интерфейса в разных библиотеках он вынесен в отдельный файл, а уже оттуда записывается в нужные библиотеки.

А в формате JSON просто описаны дополнительные инструкции о том, как конвертировать widl в ts

Немного становится страшно, что они вытягиваются из Edge. А не Edge (вместе с остальными браузерами) вытягивает их откуда-то из центрального места.

Спасибо что потратили свое время и сделали Typescript типы немножко лучше для остальных пользователей!

Вот это мне в typescript нравится. Я когда засылал простой багфикс, приняли в течении дня. А потом ещё и в релиз ноутс, упоминают всех, даже если коммит состоял из перестановки двух строк. С точки зрения открытости сообществу они очень крутые.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории