Информация

Дата основания
Местоположение
Россия
Сайт
www.directum.ru
Численность
501–1 000 человек
Дата регистрации

Блог на Хабре

Обновить
Комментарии 44
Доя подключения bem следует использовать bem-react от яндекса, он написан на typescript и весит меньше килобайта
Большой проект — это насколько? 50k+ sloc? 100k+?
Компонентов сколько мигрировали? Какие codemod может посоветуете?
Какие инструменты использовали для унификации type-guards при работе с thunk/saga?
Размер проекта примерно 114k+. 110 компонентов на ts (~200 еще остались на flow). По codemod, к сожалению, посоветовать ничего не могу, как и по type-guards (thunk используем только для getState())
Может сначала стоит изучить инструмент? Это статический анализатор, а не магическая коробка, тип списка после `filter`не становится вдруг списком чисел, так как на выходе filter тип списка тот же, что и на входе.

Если вы про то, что filter и map можно завернуть в тот же reduce или про то, что isNumber не выносить за условие — то это бред, это не повышает производительность написания продукта ни разу. Если про что-то другое — поясните.

Мде, печаль. С TS не работал, но думал это только Flow такой.

Могу посоветовать такое решение:

function isNumber (n: unknown): n is number {
    return typeof n === 'number';
}

[1, null, 3].filter(isNumber).map(n => n * 10);

const f = (n: string | number) => {
   return isNumber(n) ? n * 10 : n
}


www.typescriptlang.org/play/#code/GYVwdgxgLglg9mABDAzgORAWwEYFMBOiAFGAFyLgDWYcA7mAJTlKqJhZ6EDeAUIv4ny4oIfEigBPAA644wNogC8yxAHJ2OAqoDcPAL48eAbQCMAGjYgANlYsBmALoA6YDCtQCRVBk34GTzABDKRIlAD4FACpEEwAGBl1DCAQUKER5RWIyRFT8GDAAc0QAH0tfBnDEXgBIIRExZHQOT0ZEAH4omNjEZn0gA

P.S. только увидел, что ниже уже ответили

Верно, я как раз посмотрел на сингнатуру filter https://github.com/microsoft/TypeScript/blob/master/src/lib/es5.d.ts#L1141 и увидел, что filter его таки использует. Так что, в принципе, будет работать даже такой вариант:


[1, null, 3].filter((n): n is number => typeof n === 'number').map(n => n * 10);

С тайпгуардами отдельная проблема: сами-то они не тайпчекаются. Можно и так написать, и компилятор ничего не скажет:


function isNumber(x : unknown) : x is number {
    return typeof x === "string";
}
> Но, к сожалению, к eslint-у можно подключить только один парсер.
Можно переопределять парсер для разных типов файлов, см. пример

> Проблема: Импорт компонентов/функций из разных типов файлов.
Разве ж это проблема, если она решается парой строчек в конфигах?
Спасибо за подсказку про парсеры, будем иметь ввиду. А про импорт согласен, проблема действительно не сложная, просто в начале перехода не сразу на нее обратили внимание. Добавил в статью именно чтобы показать разный уровень сложности проблем
Я сейчас вот с таким проектом работаю:
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
JSON                            29             20              0         617229
TypeScript                    3482          20179         148729         490138
JavaScript                      35           1805           1438          18802
HTML                            17            230              7           1757
C                                1             95             28            580
CSS                              7             50             45            476
C/C++ Header                     1              9              3             27
Bourne Shell                     1              1              0              6
SVG                              1              0              0              1
-------------------------------------------------------------------------------
SUM:                          3574          22389         150250        1129016
-------------------------------------------------------------------------------

Тут огромный JSON это просто выгрузка из БД для независимости тестов от БД.
Из 500K Тайпскрипт кода 200K это новое двигло и конвертер кода, 300К сконвертированный код приложения которое в оригинале написано на ActionScript 3.0

И как же я рад что в 2016 году выбрал typescript. Ключевой момент для меня — открытость разработки, возможность обсуждать фичи, пул реквест который правит багу был смержен в мастер за 4 (!) часа. Закрытые процессы FB и близко рядом не стоят. Ну и вообще по общему впечатлению не жалею о выборе ни разу. Начал присматриваться к ts с версии 1.3 и хочу сказать что развитие впечатляющее.
Подскажите, чем вы такой отчет по проекту сделали?

Два или три года на Flow, потом на чистом JS, теперь больше года на TS.


Проблемы плюс-минус одни и те же, кроме поддержки в IDE.


Код только для TS (тайпгварды или явные as/any/object) и тут приходится писать примерно в том же обёме, причём некоторые вроде очевидные проверки TS не ловит, например, при типе возвращаемого значения T|T[]|null|undefined (привет, react-select) простой проверки !Array.isArray недостаточно чтобы исключить T[] из обработки. Кажется, выражения условия isT(val) || val === null || val === undefined тоже не понимает как исключение T[].


Некоторые типы писать очень сложно с одной стороны, а с другой типобезопасность в моём понимании из-за структурной типизации не очень: ошибки, когда при копипасте забыл заменить user на Organization, не ловит, если нужны только id и name


В целом пока типы ведут себя так как ожидаешь, то профит от использования TS/Flow есть — ловит глупые ошибки. Но непонятно компенсирует ли это ситуации, когда полдня или больше тратишь на попытки обойти сообщения о ошибках типов системой типов без явного приведения или громоздких честных тайпгвардов, а в конце-концов просто делаешь какой-то хак.

с другой типобезопасность в моём понимании из-за структурной типизации не очень: ошибки, когда при копипасте забыл заменить user на Organization, не ловит, если нужны только id и name
Если использовать Flow с классами (вместо простых объектов), то такой проблемы не будет — Flow применяет к классам номинативную типизацию (или номинальную, не уверен, как лучше).
Интересно, не знал про такое. Хотя, как по мне, выглядит это, мммм, немножно как костыли. :)

Я лично, напротив, не вижу проблемы в структурной типизации. Но может кому-то будет полезно узнать, что не обязательно страдать со структурной типизацией, когда она тебе поперёк горла.
например, при типе возвращаемого значения T|T[]|null|undefined (привет, react-select) простой проверки !Array.isArray недостаточно чтобы исключить T[] из обработки

Странно, а у меня работает.


Но на самом деле, это баг и работать оно не должно: ведь не любой T[] пройдет проверку isArray...

Я попытался упростить для примера, видимо где-то что-то упустил.


Разобрался что упустил, вам должно понравиться: не просто T[] а readonly T[]: не работает


Вот этот баг похоже https://github.com/microsoft/TypeScript/issues/17002 с патчем https://github.com/microsoft/TypeScript/pull/28916

Не совсем понял, как осуществляется взаимодействие сосуществующих TS и Flow?
Допустим, в TS-файле импортируется и используется компонент, написанный на JS+Flow, откуда TS узнаёт сигнатуру этого компонента?

А откуда узнаёт о сигнатуре JS-компонента?

Не понял вопрос.
Если речь про JS-компонент без аннотаций типов — понятно, что неоткуда, нужны отдельные libdef'ы.
Но тут-то речь о существующей кодовой базе, в которой у компонентов уже есть аннотации типов на Flow.

Нужные отдельные libdef или включение allowjs в том или ином виде. Аннотации Flow легко вырезаются и превращаются в обычные JS.

двойная проверка на null
Звучит странно и непонятно, хотелось бы больше деталей. У меня не получилось воспроизвести эту проблему, всё работает и без лишнего if'а.
Спасибо, немного поправил пример. Правда во flow песочнице ошибка так и не воспроизводиться (пробовал менял версию на нашу), а в проекте падает ошибка:
Cannot call `this.activeFormContainer.style` because property ` style ` is missing in null or undefined [1].
Спасибо, так стало понятнее.
Не очень ясно, почему type refinements неправильно отрабатывает конкретно здесь, но в целом проблемы такого рода не так редки, как хотелось бы.
FGJ, у TS с его type guards такие проблемы тоже есть (может, не этом конкретном случае, но на каком-то другом).
Тоже переводили проект с Flow на TypeScript. Мотивация — плохая диагностика ошибок и слишком большие усилия на поддержку типизации. С TypeScript работа пошла гораздо бодрее.
Во Flow сначала привлекли зависимые типы и большая строгость, но все преимущества обесцениваются сырой реализацией.
А что вы понимаете под «зависимыми типами» во Flow?
en.wikipedia.org/wiki/Dependent_type
Сейчас действительно не смог их найти в документации к Flow, но, если я правильно помню, одно время говорили об их поддержке.

"JavaScript – это один из языков с динамической типизацией. Такие языки удобны для быстрой разработки приложений"
Каким образом они более удобны для быстрой разработки?
Не первый раз слышу подобную фразу но всегда без объяснения этого удобства.

Не нужна компиляция, но сейчас есть куча инструментов для запуска компилируемых языков на лету, тот же ts-node, в частности. В GoLang это идет из коробки go run.
Вы путаете языки с динамической типизацией и интерпретируемые языки
Они удобны тем, что типы выводит компилятор и снимает с вас эту работу. Это может показаться мелочью, но когда вы передаёте какой-то сложный класс по цепочке функций, а потом переоперделяете или добавляете второй со слегка изменяющимся интерфейсом — это экономит уйму времени. Это так же имеет и недостатки, так как в больших приложениях компилятор может легко вывести типы, а программист — нет, поэтому явное указание типов просто как документация и помощь для IDE бывает полезным. Отсюда и появились языки вроде TypeScript. Можно сказать, что типизованные языки хороши для энтерпрайз, с большими приложениями и долгим сроком поддержки, а динамическая типизация — для стартапов, с коротким релизным циклом и высокой изменчивостью. Лично я всё равно миксую TypeScript и JavaScript, так как даже в рамках одного приложения разные модули могут обладать разными требованиями к стабильности и изменчивости, но это путь не для всех.

Среди мэйнстрим языков не могу вспомнить языков динамической типизацией с компилятором, выводящим типы. Пример можно? Чтоб именно компилятор по умолчанию и именно типы выводил, а не присвавиал тип динамического выражения?

Интерпретатор, но там всё равно just-in-time компиляция, не будьте занудой.
Либо что вы подразумеваете под «выводил»? Я подразумевал как раз присваивание значения любого типа, без необходимости объявлять его заранее.

Я под выводом типов подразумеваю именно вычисление типа выражения до вычисления его значения без необходимости объявлять его заранее. Тому же jit может быть очень полезно знать, что Math.sin(x) всегда возвращает number, например.

Это называется не "вывод типов", а "статическая типизация". Собственно, это и есть её определение — когда тип выражения можно узнать не вычисляя его значение.


Довольно очевидно, что среди языков с динамической типизацией вы языка со статической типизацией не нашли :-)

Я знаю чем отличаются динамическая от статической. :) Я комментировал фразу "Они [языки с динамической типизацией] удобны тем, что типы выводит компилятор и снимает с вас эту работу. Вот такого я не припоминаю, даже если считать, что "компилятор" — синоним "транслятор". Вывод типов для меня признак статического языка, не необходмый, но достаточный на практике. Статический язык без вывода типов — не экзотика. Динамический с ним — особо и представить не могу, если небрать всякие jit как деталь реализации

Вывод типов независит от компилируемости/интерпретируемости

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


Плюс очень-очень часто путают динамическую типизацию с нестрогой, с, например, неявным приведением к булевой истине значений отличных от ноля, null, пустой строки… Если что, Си — язык со статической, но не строгой типизацией. Некоторые относят его вообще к языкам без типизации как ассемблер.

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