ТюленITь 🙌 🦭

Нить рассуждений о технологиях, разработке программного обеспечения и о тюленчиках. Подписывайся в telegram.

конструкция using в грядущем typescript 5.2

В грядущем typescript 5.2 собираются добавить очень интересную и полезную фичу using. Подобное уже реализовано в других языках: В C# это using, в Go - defer. В чем основная идея. using позволяет автоматически освобождать ресурс (вызывать специальный метод для этого) после того, как покидает область видимости блока. Например у нас есть метод getResource у которого реализован метод [Symbol.dispose](). Тогда мы можем написать следующий код и метод Symbol.dispose будет выполнен автоматически в конце выполнения функции main, как если бы эта конструкций была бы завернута в блок try finally....

июня 27, 2023 · 1 минута · 184 слова · lexich

Написание адаптера для Fetch API

Кажется, что нет такого проекта, в котором не нужно делать запросы к серверу. И всегда хорошей идеей написать отдельную абстракцию для описания подобной коммуникации. Это добавляет коду не только читаемости и переиспользуемости, но и дает возможность быстро и эффективно написать тест для подобной функциональности. class NetworkService { constructor(private readonly fetch: typeof fetch) {} getUser: (): Promise<IUser> => this.fetch('/api/user').then(d => d.json()) } function getUsername(api: Pick<NetworkService, 'getUser'>) { return api.getUser().then(user => user.name); } test('getUsername', async () => { const name = await getUsername({ getUser: () => Promise....

июня 19, 2023 · 2 минуты · 378 слов · lexich

Создание параметризированных строк

Задача, которая встречается почти в каждом проекте - это создание параметризированных строк. Чаще всего подобные конструкции можно встретить роутерах, но применение можно найти во многих других местах. Обычно это выглядит примерно так: const postURL = template('{host}/posts/{id}'); const url = postURL({ host: 'http://example.com', id: 1 }); // url === 'http://example.com/posts/id' Реализовать подобное API не представляет большой сложности. Разбиваем строку с помощью регулярного выражения, подставляя реальные значения вместо переменных. // создаем regexp для разбиения const buildSeparatorVarRx = (start: string, end: string) => new RegExp(`${start}([^${start + end}]+)${end}`); // в качестве разделителя используем скобки const rx = buildSeparatorVarRx('\\{', '\\}'); export function template<T extends string>(tmpl: T) { const array = tmpl....

июня 4, 2023 · 4 минуты · 715 слов · lexich

DI в typescript в стиле Java

На работе в проекте столкнулись с достаточно распространенной архитектурной проблемой. Есть набор сервисов, зависящих друг от друга. Первоначально взаимосвязи между сервисами описывались c помощью DI через конструктор. interface Options { service1: Service1; service2: Service2; serviceN: ServiceN; } class ServiceNew { constructor(private options: Options) {} } В большинстве случаев такой подход является достаточно эффективным. Однако порой возникают ситуации, например, когда 2 сервиса зависят друг от друга и приходится инжектить зависимость через функции-геттеры....

мая 31, 2023 · 2 минуты · 348 слов · lexich

Асинхронные операции в mobx

Продолжаем нашу серию заметок: “Готовим mobx в обход документации”. В прошлый раз мы реализовали примитив Subscriber. Он очень полезный, но не у каждого в проекте есть вебсокеты или подобные генераторы данных. Что есть у каждого, так это REST API. Работа с асинхронными операциями в документации, хоть и описана, но с архитектурной стороны вызывает одни подозрения и много boilerplate кода. Есть пакет mobx-utils, который содержит метод fromPromise, но очень непредсказуемо, если обратиться к нему вне реактивного контекста и то можно получить тонну запросов на сервер....

мая 25, 2023 · 2 минуты · 330 слов · lexich