Обновить
64K+

TypeScript *

Cтрого типизированная надстройка для JavaScript

114,6
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Я отдал языковой модели доступ к продовой панели администрирования. Вот что пришлось построить, чтобы она её не сожгла

Уровень сложностиСложный
Время на прочтение18 мин
Охват и читатели4K

Полгода назад я поддерживал TypeScript SDK для одной панели администрирования. Обычная библиотека: сгенерированный из OpenAPI клиент, авторизация, ретраи, вебхуки. И в какой‑то момент я поймал себя на том, что рутинные вопросы к панели — «у кого истекает доступ на этой неделе», «почему нода отвалилась», «сколько трафика съел вот этот аккаунт» — я решаю одинаково: открываю редактор, пишу пятнадцать строк скрипта на своём же SDK, запускаю, читаю, удаляю.

Мысль напрашивалась: SDK уже типизирован, схемы уже есть, значит модель может вызывать его сама. Так появился marzban-mcp.

Дальше выяснилось, что «обернуть SDK в MCP» — это примерно 10% работы. Остальные 90% — ответ на вопрос, который в обычной библиотеке вообще не стоит: что можно доверить модели делать с боевой инфраструктурой, а что нельзя, и как эту границу выразить в коде.

Читать далее

Новости

Все пять safety-свойств Raft прошли. Две реплики разошлись

Уровень сложностиСложный
Время на прочтение12 мин
Охват и читатели12K

Реализация Raft на TypeScript под сидированной симуляцией: каждый тик, каждая задержка сообщения и каждое падение узла берутся из сида. На двадцать пятом прогоне две реплики применили разные значения — при том, что правила алгоритма выполнялись все до одного.

Интересен не сам баг, а то, какая проверка его поймала. И вопрос, который из этого следует: откуда я знаю, что остальные проверки вообще на что-то смотрят.

Читать далее

Как случайно создать облачный кроссплатформенный сервис для Excel

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели6.8K

Я работаю в офисе (вспоминается песня "Ленинграда") и моим основным рабочим инструментом уже очень долгое время является Excel. Рискую показаться предвзятым, но на мой взгляд Excel - это лучший продукт Microsoft. И вообще электронные таблицы, как класс приложений, - это абсолютно гениальное изобретение человечества. Наверное многие считают из злом, но давайте пройдемся по фактам:

Читать далее

Playwright для компонентных CAT-тестов в проекте на angular

Уровень сложностиСредний
Время на прочтение32 мин
Охват и читатели3K

Когда говорят «у нас есть тесты на Playwright», обычно представляют классический e2e-сценарий: тест открывает приложение, проходит авторизацию, переходит по нескольким страницам и работает с настоящим или почти настоящим backend.

Мы используем Playwright немного иначе.

Основной пласт UI-автоматизации в нашем Angular-проекте — это CAT-тесты. CAT в данном случае расшифровывается как component autotest. Мы поднимаем отдельный компонент или целую бизнес-форму в Storybook, открываем её в настоящем Chromium, выполняем пользовательские действия, управляем HTTP-ответами и сравниваем интерфейс с эталонными снимками.

Получается тест, который находится между unit и e2e:

Читать далее

Как я запарился считать плитку для ванной и написал свой калькулятор раскладки

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели6.6K

Затеял ремонт в ванной, дошёл до плитки — и тут понеслось. Санузел у меня Г‑образный, в углу венткороб, раскладку хочу диагональную, а «раздели площадь на плитку» вообще не работает, я это понял когда мои циферки не сошлись с тем что плиточник насчитал — разница набежала непонятно откуда.

Плиточник говорит — берите пятнадцать процентов запаса и всё. Пятнадцать процентов от плитки по 2000 с лишним за метр это уже сумма, я в столбик посчитал и решил что нет, надо по‑другому. Калькуляторы онлайн — площадь на цену умножают, я и сам умею. В CAD полез — там сначала модель строй, а мне не чертежи нужны были.

Написал своё в итоге, дальше расскажу что вышло, скрины ниже, там понятнее чем я объясню.

Читать далее

DI во фронтенде: от Context API к Composition Root

Уровень сложностиСредний
Время на прочтение15 мин
Охват и читатели5.1K

Современные веб-приложения содержат сложную бизнес-логику, которая ранее традиционно располагалась на бэкенде. С ростом сложности возникает необходимость в эффективном управлении зависимостями для поддержания тестируемости, модульности и слабого зацепления этих модулей в приложении. Принцип Инверсии зависимостей (Dependency Inversion, DIP) и его реализация в лице механизма Внедрения зависимостей (Dependency Injection, DI) становится ключевым инструментом для решения этих задач.

Читать далее

5ⁿ → 4n+1: сколько на самом деле дают редукции в explicit‑state model checking

Уровень сложностиСложный
Время на прочтение16 мин
Охват и читатели4.7K

Проверка модели полным перебором упирается в комбинаторный взрыв, и практически вся инженерия в этой области — не про сам поиск, а про то, как его избежать. Две классические техники — редукция по симметрии и редукция частичных порядков — описаны в литературе десятилетиями, но их эффект обычно приводится либо асимптотически, либо на одном показательном примере.

Ниже — измерение на работающей реализации: во сколько раз каждая редукция сокращает пространство состояний, сколько она стоит в пересчёте на состояние, на каких спецификациях она не даёт ничего, и — главное — экспериментальная проверка того, что четыре условия ample‑множества действительно необходимы, а не унаследованы из статьи без разбора.

Три результата, ради которых стоит читать дальше:

Читать далее

Как Omit {T, K} растворил типы, или что такое дистрибутивность типов в TypeScript

Время на прочтение7 мин
Охват и читатели89K

Представьте ситуацию: вы выкатываете новую фичу, а бэкендер спрашивает вас: «Слушай, а почему вместо событий — пустой объект?». Вы в шоке: «Как так — пустой объект? У меня же TypeScript, всё типизировано, такого не могло быть!». Спойлер — могло. 

Меня зовут Денис Платонов, я старший разработчик интерфейсов в Телемосте и я отвечаю за on-premise развёртывание веб-клиента Телемоста в инфраструктуре заказчика. В этой статье я расскажу о том, как безобидный на первый взгляд Omit превратил наш аккуратный тип событий в пустой объект. Заодно разберём, как работает дистрибутивность типов в TypeScript и поделимся, чему нас научил этот кейс.

Читать далее

Мой тестовый харнесс нашёл баг в моей же реализации Raft. Рассказываю, как именно

Уровень сложностиСложный
Время на прочтение4 мин
Охват и читатели6.2K

Набор тестов, который всегда зелёный, содержит непроверяемое допущение: он может ловить ошибки, а может не смотреть вообще — по цвету это неразличимо.

Я писал реализацию Raft на TypeScript и построил вокруг неё музей багов: семь экспонатов, каждый выключает ровно одно правило алгоритма и требует, чтобы харнесс поймал это — с сидом и с именем нарушенного свойства.

Один экспонат появился не по плану. Харнесс нашёл баг в самой реализации: все пять свойств безопасности держались, логи совпадали, никто не падал — и на двадцать пятом сиде две реплики разъехались навсегда. Разбираю, почему так вышло, как устроен харнесс и чего этот метод не доказывает.

Читать разбор

Как я ускорил TypeScript-типы в 15.7 раза

Время на прочтение3 мин
Охват и читатели7.2K

Иногда TypeScript думает мучительно долго. У меня это вылезло не самым приятным способом: @_chenglou — он работал над React, ReasonML и ReScript, а сейчас над Midjourney — завёл в моей библиотеке схем issue «Large TS types cause type inference slowdown».

Ну… неприятно. Но я знал, что в системе типов TS люди собирали и не такое, вплоть до Doom, — значит, тормоза лечатся, а не заложены в фундамент.

Дальше всё оказалось довольно механически. Сначала тесты на типы, чтобы ничего не сломать молча: оптимизация типов легко превращает { a: string } в { a?: string }, и никто вам об этом не сообщит. Потом замеры через @ark/attest от создателей ArkType — он считает, во сколько инстанцирований типов обходится выражение, и фиксирует это как бейзлайн, который дальше можно занести в CI. И только после этого — сама оптимизация.

Фикс в итоге оказался на одну строчку. S.Output матчился по всему типу Schema<…> — большому объекту с перегрузками, пересечённому с юнионом всех вариантов схемы, — хотя готовый тип всё это время лежал в соседнем поле ~standard. Достаточно было заглянуть сразу туда.

Извлечение типа стало дешевле в 15.7 раза и перестало зависеть от размера схемы. В статье — таблица со всеми замерами до и после, код тестов и бенчмарков и рецепт, который можно применить к своему проекту.

Читать далее

Когда setState недостаточно: как я написал транзакционный стейт-менеджер на TypeScript

Уровень сложностиПростой
Время на прочтение18 мин
Охват и читатели11K

Стейт-менеджеров в JavaScript уже столько, что идея написать ещё один выглядит немного сомнительно. Есть Redux Toolkit, Zustand, MobX, Jotai, XState и десятки менее известных библиотек. Почти для любого способа хранить состояние уже существует готовое решение. Но все же в качестве эксперимента, решил реализовать свою идею.

Читать далее

Как выжать максимум из Генотека: вайбкодим кастомный ДНК-анализатор

Уровень сложностиСредний
Время на прочтение14 мин
Охват и читатели13K

Дисклеймер: не читайте эту статью, если вы фанат традиционных ценностей и от заголовка уже хотите написать в комментах, что мне стоит изучить базу и отучиться в меде. Читайте эту статью только если вы прогрессивный, веселый и любите необычные проекты ♥ Статья носит исключительно научпоп-инженерно-юмористический характер. Не используйте самодельные скрипты для постановки диагнозов (хотя сходить на ПЦР-тест или к врачу после них никто не запрещает)!

Скажите, вы же тоже ожидали большего от интерпретаций коммерческих ДНК-тестов типа Genotek, 23andMe, Atlas? Ну вот и я не была в восторге от того, что я на 4.2% скандинавка, мне вреден арахис, и скорее всего я люблю кинзу.

В этой статье я расскажу, как я на диком азарте построила свой пайплайн анализа генома. Мы пройдем от пересборки координат и импутации 40 миллионов маркеров на суперкомпьютере TOPMed до укрощения памяти Node.js, чтобы скрипт не умер от 43 ГБ данных, а я покажу, как все устроено под капотом. Осторожно, много блоков кода и дисклеймеров!

Читать далее

Часть 1. Как я делаю backend для браузерной игры три в ряд: server-driven контент, транзакции и идемпотентность

Уровень сложностиПростой
Время на прочтение18 мин
Охват и читатели9.2K

Часть 1. Как я делаю backend для браузерной игры три в ряд: server-driven персонажи и способности, общий контракт клиента и сервера, версионирование контента, транзакции, идемпотентность и админка.

Читать далее

Ближайшие события

Astryx: дизайн-система, которой может пользоваться AI-агент

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели8.3K

В прошлой статье про StyleX я разбирал, почему компилируемый CSS выглядит логичным продолжением ветки CSS-in-JS. Одно из главных свойств StyleX для меня — предсказуемость: стили описываются в ограниченной форме, которую можно анализировать ещё до запуска приложения.

Это особенно важно в момент, когда код всё чаще пишет не только человек, но и AI-ассистент. Если инструмент допускает любую форму записи стилей, ассистент рано или поздно начнёт пользоваться всей этой свободой: добавлять магические значения, дублировать решения, обходить токены и постепенно размывать дизайн-систему. StyleX сужает пространство для таких ошибок.

Теперь Meta открыла Astryx — дизайн-систему, построенную на React и StyleX. На первый взгляд это выглядит как релиз большой библиотеки: больше 170 компонентов, темы, тёмный режим, шаблоны, CLI, всё как мы любим. Но количество компонентов здесь не самое интересное. Astryx стоит рассматривать как следующий шаг после StyleX: если StyleX делает предсказуемыми стили, то Astryx пытается сделать предсказуемой работу с интерфейсом целиком — и для человека, и для AI-агента.

Читать далее

Encode, don't stringify — как JSON.stringify вам врёт

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели6.6K

Помните, как лет 5–7 назад все сидели на Yup или Ajv и всех всё устраивало? Признаю, половину интернета устраивает до сих пор 🫡

Потом появилось «Parse, don’t validate», стало настольной книгой для кучи разработчиков и в итоге выстрелило и у нас, в JavaScript и TypeScript. Тысячи библиотек со схемами — лучшее тому подтверждение 😁

Но это уже решённая проблема, и статью вы открыли не ради неё. А вот что не решено:

Читать далее

Ускоряем drop in replace Next.js в 100 раз. Часть 1

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели7.4K

Как говорил классик: в 100 раз за Rust. Кажется, что название является кликбейтом. И такого быть в принципе не может. Но я запланировал цикл из трёх статей, в которых постараюсь рассказать, как достичь такого фантастического результата.

Читать далее

Web‑карты: от координат до изображения

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели6.7K

Статья посвящена базовым принципам работы тайловых веб‑карт. В ней рассматривается, как карта мира разбивается на небольшие изображения — тайлы, как устроен их URL и что означают параметры zoom, x и y.

На простых примерах разбирается связь между географическими координатами и положением тайла в общей сетке. Пошагово выводятся формулы преобразования долготы в координату X и широты в координату Y с учётом проекции Web Mercator.

В заключительной части показано, как с помощью дробной части полученных координат определить точное положение точки внутри тайла и отобразить её поверх изображения.

Делаем ядро тайловой веб-карты на JS

Плоть слаба: как я писал свой Wine для браузера

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели16K

Каждый год на новогодних каникулах у меня просыпается ностальгия, хочется перепройти что‑то из детства, типа «Harry Potter and the Philosopher’s Stone» от KnowWonder. И если с консольными играми всё просто (эмуляторы типа DuckStation или PCSX2 работают идеально), то с PC‑играми 32-битной эры всё сложно, особенно на Mac. Часто пока ты добьешься запуска игры, уже пропадает всякое желание ее проходить.

В этот раз я решил проблему радикально: написал свою «Windows». В браузере. На TypeScript.

Усаживайтесь поудобнее, я расскажу вам, как я полгода дебажил чужие игры двадцатилетней давности и почему на это подсел.

Читать далее

Реалтайм на WebSocket со сквозной типизацией: TypeScript, Bun, React, Point0

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели7.9K

Бывает так: есть фулстек проект, и в нём всё хорошо. Откуда-то есть сквозные типы (tRPC, генерация из OpenAPI), есть авторизация, есть основной функционал. А потом вы решаете добавить реалтайм: уведомление о новом посте в ленте, чат между пользователями, интерактивную доску. И появляется целый новый слой абстракций, в котором надо заново изобрести всё, что в проекте уже есть, только на новый лад. И дальше поддерживать две разные системы.

В своём фреймворке Point0 я добавил четыре новых реалтайм-поинта (структурные единицы наравне со страницами, лэйаутами, квери, мутациями): канал, спейс, клиентский хэндлер, серверный хэндлер. На них собирается практически любая реалтайм-функциональность, кода получается мало, и читается он интуитивно. Эти поинты несут те же свойства, что и все остальные:

код сервера и клиента живут в одном файле, компилятор вырезает клиентский код из серверной сборки, а серверный из клиентской

типизация сквозная и выводится из дженериков самого фреймворка, без генерации типов

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

Читать далее

Чему мы научились, написав на Rust среду выполнения для TypeScript

Время на прочтение17 мин
Охват и читатели9.6K

Encore зародился как фреймворк на Go, и на Go там были написаны среда выполнения, интерфейс командной строки (CLI), парсер и компилятор. Когда мы решили поддерживать TypeScript, логичнее всего было бы написать на TypeScript и среду выполнения тоже, либо достроить к среде выполнения Go какой‑нибудь мостик. Но в итоге пришли к тому, что написали новую среду выполнения с нуля на Rust.

Читать далее
1
23 ...