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

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

Как насчёт в примерах давать нормальные имена типам вместо _O, R, D?

Почему-то это стало устоявшейся практикой давать переменным типа однобуквенное имя

Это прекрасно:

Система типов TS очень выразительная -> Не надейтесь на систему типов

В случае с TS так и получается. Пока пишешь на нём, всё подсвечивается и более-менее верно. А потом типы просто выбрасываются. В рантайме на вход функции может прилететь что-то неверное и пройти в глубины, и это никак не будет предотвращено, если не писать везде рантаймные проверки. Надёжность только во время разработки, но не во время исполнения. В других языках типа C++ или C# то, что типизировано, будет таковым и в рантайме, и дополнительных проверок не нужно. Плюс к этому, TS имеет типы, несовместимые с JS, то есть попросту неверные, но при этом преобразуется в JS в итоге. Например типа void в JS нет. И функция, возвратившая промис, в TS может считаться не возвратившей ничего, и тогда понять это и перехватить исключение промиса не возможно, что приведёт к краху процесса.

Это своего рода цена, которую платишь за удобство ("всё подсвечивается и более-менее верно").

Есть ещё такое вот - rescript. Не пробовали?

Да, идеальных альтернатив пока нет. Не пробовал.

Да, сталкивался с таким плагином в официальной онлайн песочнице TS, но детально не изучал его. Сейчас глянул на список задач, нашёл среди задач extreme вида парсер JSON. Впервые я что-то весомое решил в своей жизни. А-то на том же Codewars задачи от 6 kyu и ниже не могу решить :D

Посмотрел, спасибо, и правда проще намного

Есть ещё такой лайфхак: type Inc = [1, 2, 3, 4, 5, ...]. Тогда type One = Inc[0], type Two = Inc[1].

Поскольку ограничения на рекурсию довольно жёсткие, такой подход оправдан в целях экономии 'шагов' рекурсии

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

Не подскажете, где могу узнать подробнее о реализации трамплинов на типах? Поиски выдавали только конкретные реализации на JS и TS. Интересно было бы прочитать

Хз. В кратце это когда вместо одного цикла на 100 итераций, делается цикл на 10 итераций в каждом из которых по 10 итераций. В случае типов эти циклы описываются через рекурсию.

С typescript не знаком.

Скажите, вот вы не пишете тела функций, но всё-таки, что туда можно написать? Вот, к примеру, для последней функции split, компилятор примет тело "str.split(sep);"? А какие ещё тела он примет для такого возвращаемого типа? Я что-то плохо представляю как нечто такое можно верифицировать.

Для корректной работы возвращаемого значения Вам нужно будет "урезать" тип string[], который возвращает метод str.split(sep) до более узкого типа Split<T, S> . То есть, это обычное преобразование типов. Однако без явного преобразования типа TS скажет, что string[] и Split<T, S> несовместимы. Это некоторый хак, который верен с теоретической точки зрения.
То есть, если алгоритм работы функции split будет неверным в практическом плане, то мы соответственно получим ошибку в рантайме, но при этом TS нам уже ничего подсказать на этапе разработки не сможет. Отсюда и предупреждение в статье:

Данный подход опасен, но при осторожном использовании может быть очень мощным средством

Посмотреть, как работает вывод типов можно здесь: Песочница

Спасибо.

Вот так работает хорошо:

let test = split('21,3', ',')';
let first = test[0];

Тип first выводится равным `21`.

Однако, вот так плохо:

let t = '21,3';
let test = split(t, ',')
let first = test[0];

Тип test выводится пустым массивом, и третья строчка посвечивается ошибкой. Неожиданно, кажется что split должна возвращать string[] если на вход подана string.

То же самое и с другим сложным примером:

let t = ['1', '2'];
let test = concat(...t);

Тип test здесь выводится пустой строкой. Таким образом, в обоих примерах явное приведение типов внутри функций, предлагаемое вами, содержит ошибку и является источником unsoundness (не знаю как по-русски, "противоречивость" может быть?).

Похоже, что в утверждении

Данный подход опасен, но при осторожном использовании может быть очень мощным средством

нужен особый акцент на слове "осторожном".

Я бы в своем коде не стал вообще использовать перепресвоение типа без рантайм-проверки, за одним исключением - если есть доказательство, что переприсвоение корректно. В данном случае (split и concat) даже с рантайм проверкой было бы грустно, т. к. программист не ожидает, что изменение кода подобное примерам из предыдущего комментария потенциально может ввести райнайм ошибку, и может сделать коммит не проверив.

Реалии TS, к сожалению, таковы, что unsoundness можно получить даже, казалось бы, в абсолютно нормальном коде. Недавно смотрел выступление, в котором приводился очень яркий пример с котиками и собачками. Если попытаетесь запустить, то получите ошибку в рантайме. Однако, если так посмотреть, TypeScript и не ставит своей целью обезопасить написание кода с помощью типов. TypeScript - хороший инструмент, но такой инструмент эффективен только в хороших руках. У меня не такие, поэтому родилась эта статья :D
Соглашусь с Вами, акцент на слове "осторожном" действительно нужно сделать

Тут и поспорить трудно. Однако пример из статьи на Flow ныне выдаёт ошибку абсолютно на каждых строках. Что это: ошибка или тактический ход - не знаю :D

Что-то они там с тех пор сильно сломали.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории