using in the upcoming typescript 5.2

In the upcoming TypeScript 5.2, it’s planed to add a very interesting and useful feature called using. Similar functionality already exists in other languages: in C# it’s using, and in Go it’s defer. The main idea is that using allows you to automatically release a resource (by calling a special method for this) after it exits the scope of the block. For example, if we have a method getResource that has implemented the method [Symbol.dispose](), then we can write the following code and the Symbol.dispose method will be executed automatically at the end of the main function, as if this construct were wrapped in a try finally block. ...

June 27, 2023 · 1 min · 213 words · lexich

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

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

June 27, 2023 · 1 min · 184 words · 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.split(rx); // TTemplateFunction - ??? const fn: TTemplateFunction<T> = args => array.map((item, i) => (i % 2 ? (args as Record<string, string | number>)[item] : item)).join('') as any; return fn; } Данная реализация отвечает на все наши запросы, но остается под вопросом что такое TTemplateFunction? Он конструирует из литеральной строки (string literal types) T тип-функцию, которой на вход передается объект, ключи которого должны соответствовать переменным из типа T. Возвращаемое значение будет литеральной строкой с подставленными значениями из аргументов вместо переменных из T. ...

June 4, 2023 · 4 min · 715 words · lexich

Брендированные типы в typescript

Cегодня хочется поговорить о брендированных типах в typescript. Для начала, представим, что у нас есть функция для конвертации валют. const usdToEur = (usdAmount: number, rate = 0.92) => usdAmount * rate; usdToEur(100); // === 92 eur Давайте немного улучшим ее, введя типы USD и EUR, чтобы не только название функции и коментарии к ней подсказывали нам о ее предназначении. type USD = number; type EUR = number; const usdToEur = (usdAmount: USD, rate = 0.92): EUR => usdAmount * rate; usdToEur(100); // === 92 eur Стало гораздо лучше, но фактически ничего не изменилось, тк мы можем также передавать любое число и нововведенные типы не защищают нас от ошибки. И здесь нам на помощь приходят брендированные типы. Смысл в том, что мы подмешиваем в описание типа дополнительные поля, которые по факту (в рантайме) не существуют, но при этом typescript осуществляет по ним проверку. ...

May 15, 2023 · 2 min · 225 words · lexich