# Понедельник 19 твитов
Йоу! Под конец января с вами Майк Башуров @SaitoNakamura. Много лет делал .NET, ушел во фронтенд и не жалею. Будем… twitter.com/i/web/status/1…
10:08... а на выходных отдохнем и поболтаем про образование, языки и акценты, космос и научпоп
10:08Начнем с начала тайпскрипта, то бишь с его прошлого
Появился он еще в 2012 году zdnet.com/article/micros…
, релиз 1.… twitter.com/i/web/status/1…
В то время язык был местами ближе к C# чем к JS, отсюда namespaces, classes, private/public/protected.
В целом эт… twitter.com/i/web/status/1…
10:43Итак на дворе 2012, Путин возвращется на президенское кресло после Медведева, до ES2015 еще три года (я кстати снач… twitter.com/i/web/status/1…
10:43Несмотря на то что была взята часть фич шарпа, другая часть была переосмысленна
10:55@jsunderhood И кошмар с .d.ts11:00
Пока не появился и не стал популярен Angular пользоваться Typescript было больно име… twitter.com/i/web/status/1…
Несмотря на то что в языке сразу были namespaces, назывались они в начале modules. Естественно это вызвало name cla… twitter.com/i/web/status/1…
11:15Вообще на релизе в ТС не было очень многого чем мы с вами пользуемся сейчас. Даже если не считать фичи ES2015 до TS… twitter.com/i/web/status/1…
11:20@jsunderhood Для большинства библиотек их не было. Но это было не так страшно, как то, что они устаревали и сильно… twitter.com/i/web/status/1…11:26
@jsunderhood Сейчас открыл фронтенд-проект 2013 года на angularjs/typescript и я не вижу тут ничего про npm все typ… twitter.com/i/web/status/1…11:26
@musuk Ах да, раньше была утилита typings github.com/typings/typings которая устанавливала тайпинги прямо в репу (такж… twitter.com/i/web/status/1…11:28
@musuk Я бы кстати не сказал что тот или другой подход обязательно плохой и обернется болью11:28Чем меньше и хуже каче… twitter.com/i/web/status/1…
@musuk Но если вы захотите исправить именно исходник (например чтобы потом сделать PR) будет очень неудобно, потому… twitter.com/i/web/status/1…11:29
Но 2.0 превнес наиважнейшую фичу: nullable types. Возможность сказать: "Вот здесь будет точно string/number/какой-т… twitter.com/i/web/status/1…
11:33Многие современные языки
* являются функциональными языками с монадой Maybe (Haskell, Scala, F#, OCaml, ReasonML)
*… twitter.com/i/web/status/1…
Если кому интересно, работаю я в WiseBits, Лимассол, Кипр (недавно переехал), буду тут делать комьюнити, а также я… twitter.com/i/web/status/1…
12:33Про монадки и прочее фп мы поговорим попозже, а пока вернемся к истории
Вообще, если хочется тщательно проследить… twitter.com/i/web/status/1…
12:36@musuk @jsunderhood тоже примерно в те годы исползовал angularjs + typescript. не сказал бы что было как-то больно… twitter.com/i/web/status/1…12:54
# Вторник 41 твит
Извиняюсь за перерыв, работать тоже надо (как ни странно)
Продолжаем
В 2.0 также появилась опция --skipLibCheck.… twitter.com/i/web/status/1…
16:38Варианты действий при ошибке компиляции в тайпингах
Идеальный: форкнуть существующие тайпинги, поправить ошибку, с… twitter.com/i/web/status/1…
16:44Дело просто в том что иногда такие ошибки возникают при апгрейде версии самого ТС, а времени делать целый PR нет
В… twitter.com/i/web/status/1…
16:44@jsunderhood Есть ещё один минус TS: copypastablilty со stackvoerflow и из документации к либам хромает.16:47
Там скорее… twitter.com/i/web/status/1…
@musuk Я бы не сказал что прям хромает, большинство жс кода тс проглотит, хоть и с ругательствами16:47К тому же есть в… twitter.com/i/web/status/1…
@musuk @jsunderhood Кмк это и минус и плюс. Адаптировать любой код в типы с оверфлоу легко. Так что бонус и для жс и для тс.16:48
@jsunderhood @musuk Можно ещё прочитать twitter.com/johnny_reilly/…
Отличное чтиво!
@jsunderhood @musuk Можно ещё прочитать twitter.com/johnny_reilly/…
16:48
В 2.1 появился исключительно полезный типооператор keyof. На нем строится наверное процентов 80 (люди склонны вери… twitter.com/i/web/status/1…
17:03И вы хотите его типизировать, но не просто icon: string, а чтобы можно было только plus и menu
Конечно можно напис… twitter.com/i/web/status/1…
17:03Но можно просто написать keyof typeof svg и он автоматом возьмет все свойства svg!
Самое полезное здесь конечно то… twitter.com/i/web/status/1…
17:03Подробнее про keyof здесь
typescriptlang.org/docs/handbook/…
Из минусов (на самом деле скорее особенностей): keyof работает т… twitter.com/i/web/status/1…
17:06Наверное стоит еще остановиться на typeof раз уж я его упомянул
Дело в том что для ТС при парсинге и компиляции су… twitter.com/i/web/status/1…
17:14Так как типов в рантайме нет (об этом мы с вами еще поговорим), то влиять на рантайм как бы нельзя
Но вот с помощь… twitter.com/i/web/status/1…
17:14Таким образом
const svg = {
plus: './plus.svg',
menu: './menu.svg
}
type Svg = typeof svg
// { plus: string;… twitter.com/i/web/status/1…
Лирическое отступление лирического отступления:
Особо пытливые заметили что typeof является правоассоциативным опер… twitter.com/i/web/status/1…
Возвращаемся на землю (нет, не плоскую)
Еще в 2.1 появились mapped types. Это вторая основа тайплевела который мож… twitter.com/i/web/status/1…
17:26И наконец опция с путающим названием --alwaysStrict
Она непохожа на остальные опции семейства --strict (strictNulla… twitter.com/i/web/status/1…
@jsunderhood Можно не ждать, кстати, пока фикс вольют, а добавить в репу пофикшенный файл с тайпингами (см. typesRo… twitter.com/i/web/status/1…17:36
@timocov_ Все так!17:38Я просто говорил не про тот случай когда типов недостает или они немного неправильные, а когда… twitter.com/i/web/status/1…
В 2.3 появилась важная опция --strict
Она включают кучу других опций которые делают ваши типы строже и правильней… twitter.com/i/web/status/1…
@jsunderhood Стоит сказать, что сейчас с этим проще, поскольку все (или почти) тайпинги обновляют под новые версии… twitter.com/i/web/status/1…17:48
@timocov_ Да, я где-то видел как при breaking changes кор контрибьюторы писали codemodes для definitely typed и про… twitter.com/i/web/status/1…17:48
@timocov_ А поводу несовместимости: если реально несовместимы то беда конечно17:48Я не призываю использовать --skipLib… twitter.com/i/web/status/1…
Следующим экспонатом (мы видимо в историческом музее) версии 2.3 будет --checkJs
Совместно с JSDoc это то на чем с… twitter.com/i/web/status/1…
17:53В 2.4 завезли string enums
enum Colors {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
}
Несмотря на и… twitter.com/i/web/status/1…
17:56В 2.6 добавили страшно желаемую фичу // @ts-ignore
Если где-то есть ошибка и вы хотите заткнуть компилятор, но испо… twitter.com/i/web/status/1…
@musuk @jsunderhood Не так уж все плохо.19:05Скопировал код, нажал “infer types from usage” в редакторе, получаешь впо… twitter.com/i/web/status/1…
@theKashey @boriscoder @musuk tsserver такое представляет в качестве code action pic.twitter.com/vA4guq1EVD19:43![]()
@jsunderhood Мы наоборот перешли на них, т.к. важность порядка при синке с бэками — неудобно
Вполне валидный кейс
@jsunderhood Мы наоборот перешли на них, т.к. важность порядка при синке с бэками — неудобно
19:52
@jsunderhood @boriscoder @musuk Немного усложню ваш пример. Применив автоматическое извлечение типов, мы получим… twitter.com/i/web/status/1…20:50
@neruchev @boriscoder @musuk Ммм, пример не очень корректный ибо вы здесь примешиваете проблему отсутствия нормальн… twitter.com/i/web/status/1…20:50
@neruchev @boriscoder @musuk Если же вы выразите ваш Value через костыльными номинальные типы (в ТС прижилось назва… twitter.com/i/web/status/1…20:51
@jsunderhood Еще валидный кейс: когда надо разделить внутреннее преставление от внешнего красивого апи.20:53
Например: e… twitter.com/i/web/status/1…
@MrFlashAccount а вот это уже вполне можно решить обычным объектом20:54const Colors = {
RED: 'var(--color-red)'
}
@jsunderhood @boriscoder @musuk В больших и сложных проектах такие мелочи могут очень больно ударить, ловили не раз.
Я вообще буду рад если вы (аудитория) будете делиться болью
Обсудим, может даже что-то порешаем, на крайняк посидим… twitter.com/i/web/status/1…
@jsunderhood @boriscoder @musuk В больших и сложных проектах такие мелочи могут очень больно ударить, ловили не раз.
20:57
@jsunderhood @boriscoder @musuk Спасибо, не знал что так можно!21:08
Хотя действительно выглядит слегка костыльно (и не вполне очевидно).
@neruchev @boriscoder @musuk В целом если объяснить это команде то жить с этим вполне можно (если бенефиты оправдыв… twitter.com/i/web/status/1…21:09
@jsunderhood @boriscoder @musuk К счастью тред не про флоу, от кашляющих щас лучше бежать :D21:15
На сегодня наверное все, завтра добьем историю и поддадим хардкору
21:17@jsunderhood Вот это кстати очень "боль". Имею в виду "обьяснить команде". Тяжело это. Большинство, чаще всего прот… twitter.com/i/web/status/1…
Поддерживаю
Я не виню в этом людей, но коммуникация сложная даже если ты не пытаешься что-то продать
@jsunderhood Вот это кстати очень "боль". Имею в виду "обьяснить команде". Тяжело это. Большинство, чаще всего прот… twitter.com/i/web/status/1…
21:19
Я как раз неделю назад занимался тем что продавал всякую продвинутую типизацию (сам ТС команде уже продали до меня… twitter.com/i/web/status/1…
21:21# Среда 67 твитов
@jsunderhood Хардкор - это прикручивать TypeScript к существующему JS проекту.
И в самом деле, впиливать в уже существуюший проект (особенно большой) гораздо сложнее
Но у меня больше проблем не… twitter.com/i/web/status/1…
@jsunderhood Хардкор - это прикручивать TypeScript к существующему JS проекту.
9:28
@jsunderhood @ts Типы сложные, а релизить надо вчера :D
Да, несмотря на то что конечно надо стремиться к отсутствию авралов и СРОЧНА НАДА, без этого никуда
@jsunderhood @ts Типы сложные, а релизить надо вчера :D
9:32
@jsunderhood Некогда описывать сложные типы. Приходится писать "any".9:34
@SN__PR А сложные это какие в вашем случае?9:34Сложные манипуляции с типами (mapped, conditional types) или куча разных полей с бэкенда?
@jsunderhood Сложные в моём случае === не примитивные (string, boolean, number)10:01
@SN__PR Опять же вопрос к авралам:10:01Если времени не хватает постоянно (чтобы разобраться) то бороться надо прежде в… twitter.com/i/web/status/1…
Дело в чем. Раньше когда вы не знали что будет за тип, был один выход: any
any плох тем что с ним можно делать что… twitter.com/i/web/status/1…
А с unknown вы сначала должны доказать компилятору что он не пустой, в нем есть такое поле и оно такого-то типа и… twitter.com/i/web/status/1…
10:20Для того чтобы доказать используются type refinements (они же type guards)
Выглядеть может примерно так
Можете пои… twitter.com/i/web/status/1…
10:33Но если вот такие type guards работают не очень, то что делать?
Ответ: user-defined type guards
Поиграться… twitter.com/i/web/status/1…
10:39Проблемы с ними две
-
Как видите надо много писать
-
Имплементация лежит исключительно на вас
10:41
То есть можно нап… twitter.com/i/web/status/1…
@jsunderhood Боль - unsoundness, ограниченный вывод типов по call site - много печатать тайпингов. Но это все by de… twitter.com/i/web/status/1…
Да, полностью согласен
Но у меня есть туз в рукаве
@jsunderhood Боль - unsoundness, ограниченный вывод типов по call site - много печатать тайпингов. Но это все by de… twitter.com/i/web/status/1…
10:42
Тем не менее само наличие unknown уже заставляет задуматься об избыточном использовании any, что не может не влиять… twitter.com/i/web/status/1…
10:44@timocov_ Да, я где-то видел как при breaking changes кор контрибьюторы писали codemodes для definitely typed и про… twitter.com/i/web/status/1…
В 3.1 как раз появилась возможность указывать разные версии тайпингов для разных версий компилятора… twitter.com/i/web/status/1…
@timocov_ Да, я где-то видел как при breaking changes кор контрибьюторы писали codemodes для definitely typed и про… twitter.com/i/web/status/1…
10:46
В 3.4 появилась наикрутейшая возможность const assertions, например
Раньше когда у вас была функция которая возвра… twitter.com/i/web/status/1…
10:55Характерный пример это action creators в редаксе
const createLoad = () => ({
type: 'LOAD'
})
type LoadAction =… twitter.com/i/web/status/1…
10:55Ну казалось бы стринг и стринг, что такого то
А такого то, что еще есть такая штука как discriminated unions котор… twitter.com/i/web/status/1…
10:55И для того чтобы они (discriminated unions) работали надо чтобы type был string literal, а не просто string
То ест… twitter.com/i/web/status/1…
11:01type widening это когда в результате некоторых манипуляций тип становиться менее строгим
вот мы возращаем в нашем… twitter.com/i/web/status/1…
11:01Поэтому ему надо подсказать что литерал будет иммутабельный
const createLoadAction = () => ({
type: 'LOAD'
} as… twitter.com/i/web/status/1…
as const работает не только на объектных литералах но и на обычных
то есть можно написать
const createLoadAction… twitter.com/i/web/status/1…
11:03@jsunderhoodКак ты считаешь, чем лучше транспилировать ts?
Траспилить бабелем, тайпчек отдельно
Несмотря на то что официально майки рекомендуют траспилить через tsc, бабель… twitter.com/i/web/status/1…
Как ты считаешь, чем лучше транспилировать ts?
11:05
В 3.5 наконец-то добавили хелпер Omit в стандартную поставку
В 3.6 нормально затипизировали генераторы
typescriptlang.org/docs/handbook/…
В 3.7 в срочном порядке добавили поддержку nullish coalescing и optional chaining (причем прямо с 3-его стейджа ЕМН… twitter.com/i/web/status/1…
11:11Assertion function это история про exception flow control
То есть проверили предусловия контракта и пошли дальше п… twitter.com/i/web/status/1…
11:11Еще в 3.6 пофиксили некоторые рекурсивные типы
typescriptlang.org/docs/handbook/…
Раньше можно было делать рекурсивные типы к… twitter.com/i/web/status/1…
11:16Короче вот так было можно
type Tree<T> = {
value: T,
children: Tree<T>[]
}
а вот так вот нельзя
type Json =… twitter.com/i/web/status/1…
11:16Кстати до 3.6 был интересный хак чтобы обходить такое
Дело в том что по стечению обстоятельств type вычисляется ea… twitter.com/i/web/status/1…
11:18type Json =
| string
| number
| boolean
| null
| JsonObject
| JsonArray;
interface JsonObj… twitter.com/i/web/status/1…
11:18If you’re wondering a bit about what the use-case for `import type` is used for in @typescript 3.8 - one of it’s ma… twitter.com/i/web/status/1…
В 3.8 нас главным образом ожидают очередные новые фичи ECMAScript (например top-level await), но самая мякотка в ty… twitter.com/i/web/status/1…
If you’re wondering a bit about what the use-case for `import type` is used for in @typescript 3.8 - one of it’s ma… twitter.com/i/web/status/1…
11:23
Ну вот и все про историю!
Пойду поработаю, следующий тред будет про то как я вижу идеальный проект на ТС
11:25@jsunderhood Для себя в последнее время открыл ttsc - кастомная обертка, которая поддерживает плагины. Позволяет из… twitter.com/i/web/status/1…
Про ttsc, кастомные траснформеры я буду говорить очень подробно, но сейчас между делом упомяну что
1 В целом tsc п… twitter.com/i/web/status/1…
@jsunderhood Для себя в последнее время открыл ttsc - кастомная обертка, которая поддерживает плагины. Позволяет из… twitter.com/i/web/status/1…
12:06
@timocov_ @konstantin6487 @jsunderhood Для этого существуют соурсмапы. Ну и транспилить можно в es2015, тогда код остаётся читаемым19:56
@jsunderhood Я бы наоборот не рекомендовал использовать бабель от слова совсем. Тот код, который он генерит читать потом невозможно.19:56
@timocov_ Не сказал бы что имея один и тот же таргет как-то сильно отличается эмит19:56Классы у обоих не сразу понятны… twitter.com/i/web/status/1…
@jsunderhood Разве это больше про иммутабельность чем про сужение типов, т.е. выключение type widening?19:59
@timocov_ Это не больше и меньше, это две половинки одного целого19:59Если бы не было мутабельности, не нужен бы был t… twitter.com/i/web/status/1…
@jsunderhood Кстати интересно, почему они решили добавить новый синтаксис, вместо того, чтобы заюзать старый с "пер… twitter.com/i/web/status/1…20:02
@timocov_ Потому что never это сильно больше чем бросить ошибку (особенно с точки зрения теории типов)20:02never это т… twitter.com/i/web/status/1…
@jsunderhood Мне кажется, что экосистема не развита как раз из-за того, что нет нормального способа эти плагины юзать.20:03
@timocov_ Так и есть, и то что они не открывают удобное апи плагиноке - это сознательное решение20:03Потому что иначе… twitter.com/i/web/status/1…
@jsunderhood Самая большая боль пока — это вывод ошибок в сложных типах
Дико поддержу
Кто-то где-то сказал что у статической типизации ужасный UX
И это правда так, типы обычно не говоря… twitter.com/i/web/status/1…
@jsunderhood Самая большая боль пока — это вывод ошибок в сложных типах
20:07
Следующий тред про то как я вижу идеальный проект на ТС (и почему, естественно)
Как будто нам дали требования и мы… twitter.com/i/web/status/1…
20:15Первым делом установили npm i -D typescript
И инициализировали конфигурацию npx tsc --init
Дефолты на данный момент… twitter.com/i/web/status/1…
На esModuleInterop остановимся поподробнее
Опция появилась в 2.7 и помогла сделать поведение импортов консистентым… twitter.com/i/web/status/1…
20:23Против import React from 'react' у бабеля
Реальность показала что прав был бабель: * as React это namespace impor… twitter.com/i/web/status/1…
20:23Кто хочет подробно разобраться в теме: я в свое время накатал объемную статью (осторожно, Инглиш)… twitter.com/i/web/status/1…
20:23@timocov_ @jsunderhood loose preset же есть. В нем babel тоже Class.protype.method генерирует babeljs.io/repl/#?browser…20:24
Окей, с модулями разобрались, все стрикты врубили, что дальше
Дальше стоит определиться с тем какие фичи языка исп… twitter.com/i/web/status/1…
20:29Почти все фичи которых нет хотя бы на stage 4 были введены довольно давно
Большинство новых фич не относящихся с E… twitter.com/i/web/status/1…
20:29В 2.4 завезли string enumsenum Colors {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
}Несмотря на и… twitter.com/i/web/status/1…
namespaces уже совсем мало кому нужны, не вижу смысла на них останавливаться
стоит однако заметить что в тайпингах… twitter.com/i/web/status/1…
В 2.4 завезли string enums
enum Colors {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
}Несмотря на и… twitter.com/i/web/status/1…
20:34
Начнем с того что енамов в ТС 4 вида
enum, const enum, declare enum и declare const enum
Все они имеют некоторые о… twitter.com/i/web/status/1…
20:41Извиняюсь, 6 там не к месту (но и без нее непросто)
В третьих помните я говорил чтобы получить тип от рантаймового… twitter.com/i/web/status/1…
20:43Стоит ли также упомянуть что enum врядли станет когда-нибудь частью стандарта?
И при всем при этом абсолютное боль… twitter.com/i/web/status/1…
20:51Если вам нужен объект с заранее известными полями в которых будут хранится строковые значения, возьмите объект!
en… twitter.com/i/web/status/1…
20:51если же у вас есть какое-то апи завязанное на строки, к примеру
enum RequestType {
GET: 'GET'
POST: 'POST'
}… twitter.com/i/web/status/1…
С вышеназванными кейсами видимо понятно, так когда же енам все еще полезен?
1 Чтобы 1в1 скопировать енамы с бэка и… twitter.com/i/web/status/1…
20:582 Для придавания семантики числовым опциям. Этим опять же может грешить бэк и принимать вместо строковых ключей - ч… twitter.com/i/web/status/1…
20:58Ладно, енамы, что еще?
Декораторы! С ними... Сложно.
Мне как фича языка они нравятся, НО
Есть ощущение (может кт… twitter.com/i/web/status/1…
21:12И декораторы уже кажется два раза падали с stage 3 на stage 2 с ломающими изменениями
В итоге состояние декторатор… twitter.com/i/web/status/1…
21:12Во-первых декораторы не могут влиять на типы декорируемой сущности
поэтому написать
@connect(mapStateToProps)
con… twitter.com/i/web/status/1…
В итоге при использовании компонент потребует лишние пропсы
Можно конечно написать кучу явных приведений, но это т… twitter.com/i/web/status/1…
21:12@jsunderhood Прям как класс!
Нуу кстати, да, это я зафейлил, сорян
@jsunderhood Прям как класс!
21:13
Но если уж инвестируете в декораторы (например Nest) то еще есть reflect-metadata
Это вот уж точно чисто для ангул… twitter.com/i/web/status/1…
21:20Несмотря на то что фича довольно крутая, меня очень смущает то что ее никто кроме Анга не использует
Но судя по вс… twitter.com/i/web/status/1…
21:20@jsunderhood @rm_baad @HolyJSconf typegraphql.ml очень активно используют21:55
# Четверг 30 твитов
@jsunderhood Декораторы ни разу не поднимались на stage 3
Меня поправляют
@jsunderhood Декораторы ни разу не поднимались на stage 3
6:41
@jsunderhood Декораторы в нынешнем виде пришли из-за Google, который делал своё надмножество TypeScript, называемое… twitter.com/i/web/status/1…6:42
@jsunderhood Ещё inversify есть, typeorm, typegoose и прочая куча пакетов для ORM и IoC.
Оказалось что на самом деле reflect-metadata использует много кто!
Я думал что всякие inversify живут на строковых… twitter.com/i/web/status/1…
@jsunderhood Ещё inversify есть, typeorm, typegoose и прочая куча пакетов для ORM и IoC.
7:17
@jsunderhood @ts Хороший кейс для ts-ignore, правда это скорее vscode-ignore pic.twitter.com/QfNl7Pd3AX7:20![]()
@jsunderhood @ts Для понимания: проблема в том, что нет определения модуля semantic-ui-css. Оно и не нужно, ведь эт… twitter.com/i/web/status/1…7:20
@notorious_js @ts Вообще для таких случаев можно сделать global.d.ts7:20declare module "*.css" {
const content: str… twitter.com/i/web/status/1…
@jsunderhood полагаешься на выведение типов, или пишешь их всегда явно, даже если они корректно выводятся?7:32
@sairus_frontend В простых случаях (а их большинство) полагаюсь на вывод7:32Обычно в таком выводе (хотя это скорее не… twitter.com/i/web/status/1…
I'm back in black! Давайте еще посмотрим на опции компилятора
Стоит включить --forceConsistentCasingInFileNames: д… twitter.com/i/web/status/1…
7:44То есть если кто-то с винды напишет import Component from './mYComPoNenT' это соберется у него и упадет на CI (если… twitter.com/i/web/status/1…
7:44Кейсинг импорта должен быть консистентным по проекту. То есть если один раз написали правильно, то и в остальных ме… twitter.com/i/web/status/1…
7:44@jsunderhood Это вообще лист с 4 типами! Как-то я решила использовать enum как включи для анимации в angular – пере… twitter.com/i/web/status/1…
Да, вот еще то что ключа 4 тоже может вызвать проблемы потому что это контринтуитивная фигня
@jsunderhood Это вообще лист с 4 типами! Как-то я решила использовать enum как включи для анимации в angular – пере… twitter.com/i/web/status/1…
7:53
module выставляем в ESNext: собирать наверняка будем каким-нибудь вебпаком или роллапом и это позволит использовать… twitter.com/i/web/status/1…
7:59От компилятора переходим к организации проекта. Сразу советую создать в корне папку typings и указать ее в typeRoot… twitter.com/i/web/status/1…
8:12Также я считаю всевозможные опции типа webpack alias, tsconfig.paths etc. вредными
Почему? Это нестандартная фича… twitter.com/i/web/status/1…
8:19А ТС вам и говорит, не знаю что за myRoot, он же не знает ничего про вебпак
Хорошо, добавили в tsconfig.paths, ТС… twitter.com/i/web/status/1…
8:19Вы наверняка спросите, а как тогда быть c
import Something from '../../../../../../this/is/root/then/its/this/fol… twitter.com/i/web/status/1…
8:41Про использование symbolic links в кодовой базе даже говорить не хочется
Поэтому файловую систему нужно использова… twitter.com/i/web/status/1…
8:41Кратко, вместо логической группировки
actions/notifications.ts
actions/chat.ts
reducers/notifications.ts
reducers… twitter.com/i/web/status/1…
В редаксе это называется ducks, детали могут варьироваться, но я думаю общая мысль понятна
freecodecamp.org/news/scaling-y…
8:45Rule of a thumb: не создавать папку без надобности, в случае необходимости стараться группировать по функционалу
Э… twitter.com/i/web/status/1…
8:50Пока сделаем паузу, потом продолжим про всякие фп концепты и как мы будет их использовать в нашем проекте
8:53@jsunderhood @rm_baad @HolyJSconf Не, ну а как ты будешь работать с декораторами без рефлекта? Используют конечно9:52
@amel_true @rm_baad @HolyJSconf Кажется я неверно понимал опцию9:52Я думал что думал что некий рефлект (имя свойств н… twitter.com/i/web/status/1…
@jsunderhood ты вроде шаришь, расскажи плз как без боли (диких хелперов) сделать Conditional optional type
или вр… twitter.com/i/web/status/1…
Это распостраненная ошибка - делать перегрузки через conditional, обычно это заканчивается болью
Перегрузки можно… twitter.com/i/web/status/1…
@jsunderhood ты вроде шаришь, расскажи плз как без боли (диких хелперов) сделать Conditional optional type
9:59
или вр… twitter.com/i/web/status/1…
1 Стандартный встроенный способ
typescriptlang.org/docs/handbook/…
function foo(arg: { a: string })
function foo(arg: { b: st… twitter.com/i/web/status/1…
2 То же самое можно выразить через юнион инвариантов
type Arg = { a: string } | { b: string } | { a: string, b: st… twitter.com/i/web/status/1…
9:59@cakeinpanic @jsunderhood В webstorm есть. Можно еще и ренеймить строки в alias'ах, а также заменить такой type ali… twitter.com/i/web/status/1…10:40
@cakeinpanic @jsunderhood Он есть, но его нужно явно вызывать11:26
# Пятница 47 твитов
@jsunderhood Не согласен с paths - по другому монорепу не настроить7:47
@b2whats Ну да, монорепе это необходимое зло как мне кажется. Я больше про неоправданне использование7:47
@ch_ronik @jsunderhood ну конкретно для "непустого объекта" - Input extends {[key:
never]: any} ? never : Optional<Type>
Сева врывается с хардкорчиком
@ch_ronik @jsunderhood ну конкретно для "непустого объекта" - Input extends {[key:
7:58
never]: any} ? never : Optional<Type>
Вчера вечером забухал (шучу, были дела) поэтому продолжаем с утреца
8:00Где код писать понятно, как код писать понятно, но какой код писать??
Давайте поглядим на всякие штуки которые в т… twitter.com/i/web/status/1…
8:01Начнем с инвариантов. Если ко/контра вариантность может показаться сложной для понимания, то в инвариантах сложное… twitter.com/i/web/status/1…
8:11Пример: сколько возможных состояний у типа?
type Data = {
data?: string
loading?: boolean
error?: Error
}
П… twitter.com/i/web/status/1…
8:11@jsunderhood Ну, вообще, если хочется, то ФС позволяет. Есть несколько способов, и, в частности, `GetFinalPathNameB… twitter.com/i/web/status/1…8:12
@jsunderhood Идеальный проект остаётся идеальным не так уж долго 🙄
Все так, но нигилизм здесь не слишком полезный. Как говорится жизнь говно, но мы с лопатой!
@jsunderhood Идеальный проект остаётся идеальным не так уж долго 🙄
8:57
Но сколько состояний в реальности? Вероятно 4
| { loading: false }
| { loading: true }
| { data: string, loading:… twitter.com/i/web/status/1…
На таком маленьком примере не очень понятно в чем профит, но такой подход зачастую отлично ложиться на разные домен… twitter.com/i/web/status/1…
9:29Опять же если выражать это через опциональные поля выйдет как-то так
{
username: string
role: 'regular' | 'gol… twitter.com/i/web/status/1…
Пишем
const renderSubscriptionEnd = (date: Date) => {...}
if (user.role === 'gold')
renderSubscriptionEnd(user.… twitter.com/i/web/status/1…
Окей, давайте проверим
const renderSubscriptionEnd = (date: Date) => {...}
if (user.role === 'gold' && user.subsc… twitter.com/i/web/status/1…
9:29Давайте объясним это компилятору!
type BaseUser = {
username: string
}
type RegularUser = BaseUser & {
role:… twitter.com/i/web/status/1…
И теперь тот же самый код работает!
const renderSubscriptionEnd = (date: Date) => {...}
if (user.role === 'gold')… twitter.com/i/web/status/1…
9:29Потому что раньше было 4 варианта юзера
{ role: 'regular' }
{ role: 'regular', subscriptionEnd: new Date() }
{ rol… twitter.com/i/web/status/1…
@jsunderhood +updating9:32
+deprecated
И с ними ошибка играет новыми красками
И компилятору легче просечь что вы имели ввиду
Этим мы получили тот самый discriminated union о котором я говорил… twitter.com/i/web/status/1…
9:44А знаете что еще классно на это ложится? Экшены в редаксе!
Так как type это у нас string literal (к тому же с помо… twitter.com/i/web/status/1…
9:44Также можно делать exhaustive checking. Это следующая фигня, если мы выразим те экшены которые обрабатывает редьюсе… twitter.com/i/web/status/1…
9:48type LoadAction = { type: 'LOAD' }
type SuccessAction = { type: 'SUCCESS' }
const reducer = (state, action: LoadAc… twitter.com/i/web/status/1…
9:48Работает это так, что ТС зная что приходят два вот таких экшена (которые он умеет отличать друг-от-друга, hence the… twitter.com/i/web/status/1…
9:51never обладает следующими свойствами
never is assignable to anything
nothing except never is assignable to never… twitter.com/i/web/status/1…
Соответсвенно когда мы забудем обработать какой-то экшен то ТС будет ругаться что этот экшн not assignable to never… twitter.com/i/web/status/1…
10:01case 'ACTION':
return {
...state,
blaba
}
При слиянии потеряли 'return {' и потом вернули '{', а retur… twitter.com/i/web/status/1…
10:01Теперь о номинальных типах. Номинальная совместимость (по имени) противопоставляется структурной совместимости (по… twitter.com/i/web/status/1…
10:57А например в C# нет
class A { public field: string }
class B { public field: string }
void Foo(obj: B) {}
Foo(new A()) // Ошибка
10:57Так вот, о номинальных типах. Во-первых в ТС их нативно нет, приходится костылить Во-вторых, собственно, нафига?
С… twitter.com/i/web/status/1…
10:57Например id у разных сущностей. Представим что у нас есть компонент который принимает id юзера и грузит его карточк… twitter.com/i/web/status/1…
11:00На помощь приходят брендированные типы
type UserId = number & { readonly __brand: unique symbol }
declare functio… twitter.com/i/web/status/1…
11:06@jsunderhood По факту11:15enum Colors {
Red: 'red',
Blue: 'blue'
}это сочетание объекта
const Colors = {
Red… twitter.com/i/web/status/1…
@i_kabirov 1) Тип можно вывести2) Второй вопрос не понял
11:15Но можно просто написать keyof typeof svg и он автоматом возьмет все свойства svg!
Самое полезное здесь конечно то… twitter.com/i/web/status/1…
@jsunderhood 1. Я не про ключи, я про union значений11:15
@i_kabirov Если вам зачем-то нужен юнион значений (зачем кстати) то можно сделать11:15const colors = {
RED: 'red',… twitter.com/i/web/status/1…
@i_kabirov Про числа я считаю что енам нормНо в целом никто не мешает сделать так
const… twitter.com/i/web/status/1…11:152 Для придавания семантики числовым опциям. Этим опять же может грешить бэк и принимать вместо строковых ключей - ч… twitter.com/i/web/status/1…
Таким же образом можно брендировать и объекты, чтобы защититься от похожего по структуре, но неподходящего объекта… twitter.com/i/web/status/1…
11:17И напоследок немного хардкора: opaque types
Opaque (непрозрачный) type это такой тип который
1) Номинальный
2) Ум… twitter.com/i/web/status/1…
Их опять же в ТС нет поэтому будем костылить. Кода там сильно больше поэтому вот плейграунд (он почему-то показывае… twitter.com/i/web/status/1…
14:05В чем прелесть? Прелесть в том что так мы инкапсулируем внутреннюю структуру нашего игрового поля (как в ООП), но п… twitter.com/i/web/status/1…
14:05В моем примере внешний пользователь вообще ничего не знает про Game, но естественно можно искапсулировать по частям… twitter.com/i/web/status/1…
14:05Да, писать довольно муторно и неудобно, но это просто потому что нет нативной поддержки
Во flow это opaque (через… twitter.com/i/web/status/1…
14:06Вот такие у меня мысли по поводу того как писать на ТС
Следующий тред будет про Reason и немного про другие языки
14:08@jsunderhood Ухх эти типы! Я вот до сих пор не понимаю в чем отличие interface и type в последних версиях TS 🤯 В од… twitter.com/i/web/status/1…
Точно, забыл, очень популярный вопрос
Стоит использовать type
* & (intersection) можно выразить через extends, а… twitter.com/i/web/status/1…
@jsunderhood Ухх эти типы! Я вот до сих пор не понимаю в чем отличие interface и type в последних версиях TS 🤯 В од… twitter.com/i/web/status/1…
16:22
* У interface корявенький синтаксис для того случая когда интерфейс - функция
interface Foo {
(arg: Arg): Return… twitter.com/i/web/status/1…
Кстати до 3.6 был интересный хак чтобы обходить такоеДело в том что по стечению обстоятельств type вычисляется ea… twitter.com/i/web/status/1…
interface нужно использовать когда:
1) Вы пишете библиотеку: ибо interface поддерживает declaration merging, что п… twitter.com/i/web/status/1…
Кстати до 3.6 был интересный хак чтобы обходить такое
Дело в том что по стечению обстоятельств type вычисляется ea… twitter.com/i/web/status/1…
16:25
@jsunderhood Интерфейс выгоден, когда ты создатель либы и хочешь дать возможность людям играться с твоими типами. П… twitter.com/i/web/status/1…
Даже не то что выгоден, по возможности обязателен
Спасибо за бдительность однако
@jsunderhood Интерфейс выгоден, когда ты создатель либы и хочешь дать возможность людям играться с твоими типами. П… twitter.com/i/web/status/1…
16:30
# Суббота 51 твит
Теперь повысим градус типизации и ФП почти до финала: поговорим о моей тайной (на самом деле не очень) любви: Reaso… twitter.com/i/web/status/1…
17:54Во-первых во флоу есть полноценный вывод типов
В ТС весь вывод работает вниз по АСТ (с уточнениями)
Это означает ч… twitter.com/i/web/status/1…
17:54И с возвращаемым типом тоже справится (хотя и не всегда)
const foo(a: { field: string }) => a.field
17:54А вот аргументов функции уже нет, потому что объявление функции должно быть до ее вызова
const foo = (a) => a
foo… twitter.com/i/web/status/1…
17:54Так вот флоу это разрулит!
Он как-бы решает огромное уравнение где типы это переменные и смотрит сходится все или… twitter.com/i/web/status/1…
17:54Таким образом, в теории, можно вообще не писать типы!
То есть статические проверки у нас есть, а типы мы не пишем! Isn't that wonderful
17:54Дико поддержуКто-то где-то сказал что у статической типизации ужасный UX
И это правда так, типы обычно не говоря… twitter.com/i/web/status/1…
На практике конечно не все так гладко. Я уже говорил что у типизации плохой UX
Но использ… twitter.com/i/web/status/1…
Дико поддержу
Кто-то где-то сказал что у статической типизации ужасный UX
И это правда так, типы обычно не говоря… twitter.com/i/web/status/1…
18:15
Может быть два модуля которые встречаются в третьем месте. Ошибка может быть как в середине так и в самом модуле, н… twitter.com/i/web/status/1…
18:15Все что внутри наоборот типизировать не стоит, ибо это усложняет рефакторинг (явно аннотирование публичного контракта же упрощает)
18:15@jsunderhood К сожалению, это лишь в теории. Чем больше кода в проекте, тем больше он становится похожим на эту гиф… twitter.com/i/web/status/1…18:15
Есть еще одна интересная особенность систем типов и систем вывода типов: чем более экпрессивна система типов, тем с… twitter.com/i/web/status/1…
18:18В итоге трейдоффы на трейдоффах, грустно конечно, но что поделать
Тем не менее вывод типов это крутая штука и не с… twitter.com/i/web/status/1…
18:22Во флоу есть нативные opaque типы через которые также можно делать номинальные типы
18:22Во флоу также есть более интересные utility types, например $Call
flow.org/en/docs/types/…
Кто-то может возразить ч… twitter.com/i/web/status/1…
18:32То есть если функция возвращает разное в разных случаях (читай перегрузки) то флоу высчитает соответствующий тип
Т… twitter.com/i/web/status/1…
18:32Это я все не к тому что ТС плохой и не к холивару, а к тому что стоит всегда интересоваться тем что происходит вне… twitter.com/i/web/status/1…
18:34Еще немного истории, был такой язык OCaml сделали в 1996 году. Это был (и есть) мультипарадигменный язык из ML семе… twitter.com/i/web/status/1…
18:43Язык очень хороший и Фейсбук думал как бы с его помощью делать фронтенд круче. Первая попытка видимо была флоу, но… twitter.com/i/web/status/1…
18:48Потому что им в голову пришла другая идея: а что если писать фронтенд на окамле и компилировать в жс? Идея конечно… twitter.com/i/web/status/1…
18:54Слишком чужеродный синтаксис, слишком неприятно мапится на JS.
Хорошо, а что если сделать синтаксис гораздо ближе… twitter.com/i/web/status/1…
18:54That's how Reason was born. Что радует отдельно - остается верным этому по сей день. Прежде чем мы перейдем к самом… twitter.com/i/web/status/1…
19:041) Несмотря на то что он general purpose, reason изначально придуман чтобы компилироваться в жс. Для F# есть Fable,… twitter.com/i/web/status/1…
19:082) Опять же несмотря на то что он для веба, он имеет практически полную AST совместимость с OCaml. То есть вы может… twitter.com/i/web/status/1…
19:13А экосистема (в том числе пакетов) будет одна! На самом деле экосистемы две: веб и натив, но про натив будет потом… twitter.com/i/web/status/1…
19:13@jsunderhood Не уверен, что было именно так. До Reason в недрах Bloomberg был создан Bucklescript для компиляции OC… twitter.com/i/web/status/1…
Это очень важное дополнение, спасибо большое
Тут стоит упомянуть то что OCaml и до bucklescript умел компилиться в… twitter.com/i/web/status/1…
@jsunderhood Не уверен, что было именно так. До Reason в недрах Bloomberg был создан Bucklescript для компиляции OC… twitter.com/i/web/status/1…
19:18
Bucklescript же придумал новый очень тонкий рантайм и stdlib (Belt) который позволил это все реально использовать д… twitter.com/i/web/status/1…
19:18@jsunderhood На этой неделе просто рекорд добавленных в закладки тредов. Человек аккумулирует кучу знаний в простой… twitter.com/i/web/status/1…
Рад стараться!
@jsunderhood На этой неделе просто рекорд добавленных в закладки тредов. Человек аккумулирует кучу знаний в простой… twitter.com/i/web/status/1…
19:19
3) Язык и экосистема активно развиваются. Я помню как смотрел доклад Patrick Stapfer про reason в 2017, помню как н… twitter.com/i/web/status/1…
19:294) Комьюнити небольшое (по сравнению с тем же ТС), но фб действительно в это вкладывается. На дискорде сидят кор ко… twitter.com/i/web/status/1…
19:31@jsunderhood Блумберьх подарил нам хороший бэкенд, а мордокнига — фронт языка, которого js-ники не боятся. Слава OC… twitter.com/i/web/status/1…19:32
Во-вторых есть компилятор (bucklescript.github.io) который имеет очень тонкий рантайм и стандартную библиотеку (Be… twitter.com/i/web/status/1…
19:45Я сначала подумал что это лажа. Но со временем понял приемущество такого подхода. Ведь несмотря на то что ризон гор… twitter.com/i/web/status/1…
19:47@jsunderhood Ну совсем не писать нельзя. Но достаточно описать аргументы функций/классов которые экспортятся.
Спасибо, я забыл упомянуть что флоу как раз использует эту концепцию
@jsunderhood Ну совсем не писать нельзя. Но достаточно описать аргументы функций/классов которые экспортятся.
19:48
В-третьих в нем есть функциональные компоненты, иммутабельные списки (в которые быстро писать в начало), рекорды и… twitter.com/i/web/status/1…
19:55В-четвертых в нем есть те структуры которые более похожи на жс, мутабельные массивы, Js.Dict для объекта как мапы и… twitter.com/i/web/status/1…
19:58@jsunderhood 🤦♂️Так говорят только хейтеры flow.А теперь посмотри сюда и скажи насколько flow заброшен.… twitter.com/i/web/status/1…
На самом деле я рад что флоу продолжает развиваться
Но так или иначе фб в какой-то момент потерял доверие комьюнит… twitter.com/i/web/status/1…
@jsunderhood 🤦♂️Так говорят только хейтеры flow.
А теперь посмотри сюда и скажи насколько flow заброшен.… twitter.com/i/web/status/1…
20:03
В-пятых в нем удобный interop с js (привет Elm)
reasonml.github.io/docs/en/interop
Что еще прикольней так это то что помимо т… twitter.com/i/web/status/1…
20:08В-шестых в нем есть first class поддержка React
reasonml.github.io/reason-react/d…
Вот так выглядит функциональный реакт комп… twitter.com/i/web/status/1…
20:11Получается семантичненько
open Path
let root = create("/")
let myFolder = create("saito/code")
let myPath = root // myFolder
Тут я использовать еще одну фичу: синтаксис открытия модуля
Вообще все модули находяться в глобальной области види… twitter.com/i/web/status/1…
20:26Но Path.// выглядит особенно уродливо. К счастью есть scoped open module
Path.(
// мы открыли модуль пока мы в (… twitter.com/i/web/status/1…
Но опять же, это все документация и насущное, вернемся к практике
Давайте о том что же в ризоне нет/сильно недостает
20:331) Нет сормапов. В этом ключе читаемые скомпилированные исходники (а там кстати ES5) становятся особенно полезными.… twitter.com/i/web/status/1…
20:332) Нет async/await. Надежды есть, в окамл 4.08 завезли сахар для монад (а промис это почти монада), похожий на comp… twitter.com/i/web/status/1…
20:363) Есть некоторые проблемы с динамическими импортами. Во всяком случае были год назад, тогда на ReasonConf чуваки и… twitter.com/i/web/status/1…
20:38Но в целом только вот эти три крупные проблемы (во всяком случае которые испытал я)!
20:39Ах, ну да, еще то что любой другой фреймворк (вуй, ангуляр) кроме реакта завести в ризоне будет крайне тяжело
Либы… twitter.com/i/web/status/1…
20:43Тут я скину несколько ссылок
Доки ризона
reasonml.github.io/docs/en/what-a…
Доки reason-react
reasonml.github.io/reason-react/d…
Доки b… twitter.com/i/web/status/1…
20:44@jsunderhood насчёт типизации, смотрел Idris?
Сам руками не трогал, но coq и idris это конечно круто
Кому интересно про типы
youtu.be/nFtO6419A5k… twitter.com/i/web/status/1…
@jsunderhood насчёт типизации, смотрел Idris?
21:29
# Воскресенье 36 твитов
Did you ever implement (or try) event listener pattern by youself?
Попросили ретвитнуть, сложно отказать, ответьте на опрос если не сильно лень
Did you ever implement (or try) event listener pattern by youself?
16:50
Сегодня мой последний день здесь, я конечно порядком подустал за неделю, но и все донести тоже не успел
Поэтому по… twitter.com/i/web/status/1…
17:08Итак, вот у нас ест фронтенд который как-то получает данные от бэкенда
Если мы используем статическую типизацию то… twitter.com/i/web/status/1…
17:15Если рассмотреть типичную ситуацию с Rest Api и Json то это будет выглядеть как-то так
type User = { id: number }… twitter.com/i/web/status/1…
17:15@jsunderhood На самом деле разруливает он данный случай не так хорошо как могло быть. Есть 2 ветки систем типов: Hi… twitter.com/i/web/status/1…
Да, согласен, отличное дополнение
@jsunderhood На самом деле разруливает он данный случай не так хорошо как могло быть. Есть 2 ветки систем типов: Hi… twitter.com/i/web/status/1…
17:24
Но здесь на самом деле происходит неявная конвертация из any в User! Потому что на самом деле нет никаких гарантий… twitter.com/i/web/status/1…
17:33Но зачем мы тогда пишем типы, включаем strict если оно все равно может спокойно упасть в рантайме по совершенно бан… twitter.com/i/web/status/1…
17:33Есть радикальные способы: смена способа общения на такую, которая гарантирует проверку данных: тот же protobuf скаж… twitter.com/i/web/status/1…
17:33Для того чтобы доказать используются type refinements (они же type guards)
Выглядеть может примерно такМожете пои… twitter.com/i/web/status/1…
Но что же делать если на GraphQL и даже Swagger бэкендеры не соглашаются (например это внешний сервис), а проверять… twitter.com/i/web/status/1…
Для того чтобы доказать используются type refinements (они же type guards)
Выглядеть может примерно такМожете пои… twitter.com/i/web/status/1…
17:41
Наивным подходом будет просто писать валидаторы руками. Взяли какой-нибудь github.com/ianstormtaylor… и написали
17:41import { struct } from 'superstruct'
type User = { id: number }
const User = struct({
id: 'number',
})
const g… twitter.com/i/web/status/1…
17:41Проблема здесь я думаю налицо: как держать тип и валидатор в синхронизации? Любое изменение как валидатора, так и т… twitter.com/i/web/status/1…
17:44Чтобы удобно синхронизировать их, нужно иметь single source of truth. Их потенциально тут два: либо тип, либо валид… twitter.com/i/web/status/1…
17:47Короче, можно написать валидатор и из него уже вывести тип, комбинируя валидаторы! Самый известный представитель эт… twitter.com/i/web/status/1…
17:47В целом отличный подход для старта свежего проекта, но не без недостатков
1) Использование вывода там на полную ка… twitter.com/i/web/status/1…
17:492) Развесистая фигня, требующая времени чтобы понять что тут к чему
3) Непростая интеграция в существующий проект
17:50Альтернативой будет взять тип и по нему сделать валидацию. Это вполне распространенный подход в ООП языках которые… twitter.com/i/web/status/1…
18:10Точнее типы конечно есть, да не те. Мы то хотим сделать валидацию по type User = { id: number }, но при компиляции… twitter.com/i/web/status/1…
18:10@jsunderhood У меня всего один вопрос. Как этим пользоваться если я не упоротый функциональщик? Я честно пытался, о… twitter.com/i/web/status/1…
Да, есть такое, io-ts апи очень фпшное и завязано на Either из fp-ts
Я бы предложил не мучится и написать хелпер к… twitter.com/i/web/status/1…
@jsunderhood У меня всего один вопрос. Как этим пользоваться если я не упоротый функциональщик? Я честно пытался, о… twitter.com/i/web/status/1…
18:19
Что-то типа
import * as t from 'io-ts'
import { isRight, Either } from 'fp-ts/lib/Either'
const User = t.type({… twitter.com/i/web/status/1…
18:19// бросит ошибку в случае ошибки валидации
const user = eitherToThrow(
User.decode(
JSON.parse('{"userId":1,"… twitter.com/i/web/status/1…
Вариант номер раз: отправить информацию о типах в рантайм. Это как раз и есть reflect-metadata о которых мы говорил… twitter.com/i/web/status/1…
18:261) Декоратор должен быть повешен на поле реального объекта или класса, то есть вы не можете написать
type User = {… twitter.com/i/web/status/1…
18:26Получается вот это pic.twitter.com/qziBDHvo3p
@jsunderhood Можно использовать github.com/aeirola/io-ts-…18:33
Я даже написал рабочую либу!
Вообще с помощью такого подхода можно делать еще много всяки… twitter.com/i/web/status/1…
18:36Но конечно с такой силой приходят и недостатки. Никакие из них не являются нерешаемыми (разве что один), но я начал… twitter.com/i/web/status/1…
18:431) Пока это работает только через typescript transformer
Я написал доки как интегрировать это с ts-loader и ts-node… twitter.com/i/web/status/1…
2) Пока нет поддержки кастомных валидаторов
А это crucial thing, чтобы можно было написать валидатор для UUID, ISO… twitter.com/i/web/status/1…
18:49Планирую поддержать это через user type guards и Branded types
import _isUuid from 'is-uuid'
type Uuid = string &… twitter.com/i/web/status/1…
18:493) Проблема связанная конкретно с тем что мы фактически имплементируем c++ templates
github.com/ts-type-makeup…
Для к… twitter.com/i/web/status/1…
18:54Но если кто-то сделает
const myValidate = <T>(jsonStr: string) =>
validate<T>(JSON.parse(jsonStr));
То нам прид… twitter.com/i/web/status/1…
18:59Соответственно я сначала должен найти вызовы моей функции. Если я нахожусь в теле другой функции дженерик которой п… twitter.com/i/web/status/1…
18:59Я призываю компиляторщиков которые наставят меня на путь истинный и подскажут что курить и как с этим бороться
19:00Вот такие пироги! Ставьте звездочки, а также обратите внимание что либа имеет полный набор честных e2e (если можно… twitter.com/i/web/status/1…
19:02И на этой позитивной ноте я с вами прощаюсь (в реплаях может еще поотвечаю)! С вами был Майк Башуров aka… twitter.com/i/web/status/1…
19:14# Ссылки
github.com
- https://github.com/typings/typings
- https://github.com/ianstormtaylor/superstruct
- https://github.com/aeirola/io-ts-promise
- https://github.com/ts-type-makeup/superstruct-ts-transformer
- https://github.com/ts-type-makeup/superstruct-ts-transformer#%EF%B8%8F-usage-limitations-%EF%B8%8F
www.typescriptlang.org
- https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types
- https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-6.html#strict-function-types
- https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-6.html#stricter-generators
- https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#more-recursive-type-aliases
- https://www.typescriptlang.org/docs/handbook/functions.html#overloads
other
- https://www.zdnet.com/article/microsoft-typescript-can-the-father-of-c-save-us-from-the-tyranny-of-javascript/
- https://babeljs.io/repl/#?browsers=&build=&builtIns=false&spec=false&loose=true&code_lz=MYGwhgzhAEAiCmBbA9tA3gKGtAJsgysovAC4AWAlgHYDmAFAJToC-GzQA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Ces2015-loose&prettier=false&targets=&version=7.8.3&externalPlugins=
- https://typegraphql.ml/
- https://www.freecodecamp.org/news/scaling-your-redux-app-with-ducks-6115955638be/
- https://flow.org/en/docs/types/opaque-types/
- https://flow.org/en/docs/types/utilities/#toc-call
- https://bucklescript.github.io/
- https://reasonml.github.io/docs/en/interop
- https://reasonml.github.io/reason-react/docs/en/intro-example
- https://reasonml.github.io/docs/en/what-and-why
- https://reasonml.github.io/reason-react/docs/en/installation
- https://youtu.be/nFtO6419A5k