×Закрыть

TypeScript как будущее энтерпрайзного JavaScript. Часть 2

В первой части мы говорили об основных новшествах TypeScript относительно JavaScript. В этой части рассмотрим вопрос начала нового проекта на TypeScript, а также вопрос миграции существующего проекта. Отдельно обсудим случай миграции проекта, использующего RequireJS. И, наконец, познакомимся с планами развития языка TypeScript.

Новый проект на TypeScript — с чего начать

Весь потенциал TypeScript можно раскрыть, если весь код проекта будет написан на TypeScript. Если это возможно, то у вас появляется шанс писать код, который будет самодокументриуемым, с четкими контрактами интерфейсов.

Все начинается через пакетный менеджер npm. На старте нужны:
1. typescript — компилятор языка;
2. typings — менеджер пакетов с декларациями типов и классов для внешних библиотек (о нем чуть позже).

Итак, ставим в системные npm-пакеты компилятор и менеджер деклараций для внешних библиотек, затем инициализируем файл с настройками компилятора:

$ npm install -g typescript typings
$ tsc --init
message TS6071: Successfully created a tsconfig.json file.

Посмотрим, что же вышло. В папке появился один новый файл tsconfig.json — это файл настроек компилятора:

$ cat tsconfig.json
{
   "compilerOptions": {
       "module": "commonjs",
       "target": "es3",
       "noImplicitAny": false,
       "outDir": "built",
       "rootDir": ".",
       "sourceMap": false
    },
    "exclude": [
       "node_modules"
    ]
}

Это конфигурация по умолчанию. Я пройдусь лишь по ней, полный перечень возможных настроек в виде аргументов для командной строки можно найти здесь. Возможно, для вас не составит труда разобрать JSON schema формата этого файла.
Я кратко опишу отдельные настройки.

Module

TS родился и развивается не в вакууме, даже несмотря на то, что это продукт Microsoft. Авторы языка знают о том, что JS готовят по-разному:
— Для серверного применения, загрузка внешних зависимостей происходит синхронно — commonjs;
— В браузерных решениях могут применять RequireJS — amd;
— umd, system, es6, es2015 для более современных условий (или с применением соответствующих полифилов).

Для всех этих видов модулей, компилятор генерирует соответствующий код.

То есть в своем коде вы используете:

// de.ts
import { A, B, C } from 'classes/abc';

export class D {};

class E {};

export default E;

А в другом модуле:

// x.ts
import XX from "classes/de";
import { D as deD } from "classes/de";

Весь этот синтаксис будет транслирован в нужный формат.

AMD-модули

Один из самых нестандартных вариантов — это AMD-модульность от RequireJS. Уж не знаю почему, но RequireJS, по моему мнению, проиграл и скоро будет забыт. Зря, но его не используют.

Но так как все же остались большие проекты, которые просто не могут позволить себе жить без менеджера зависимостей, то следует рассказать о тонкостях AMD в мире TS. Мне до многого приходилось доходить чуть ли не через раскапывание исходного кода компилятора, что не делает чести официальной документации (к моменту написания заметки документацию дополнили).

Пример модуля:

///<reference path="../../../../typings/browser.d.ts" />
///<amd-dependency path="jQuery" name="$" />
///<amd-module name="specialName" />
import { IOptions, Modes } from 'classes/interfaces';
import { Toolbar } from 'classes/editor/toolbar/toolbar';
export class Something {
    public toolbar: Toolbar
    constructor(options: IOptions) {
        var x = new Modes();
        this.toolbar = null;
    }
}

Разберем пример почти построчно:

/// — три слеша дают понять компилятору, что это инструкции для него, а не просто комментарии.

///<reference path="../../../../typings/browser.d.ts" /> — разъясняет компилятору, где искать декларации популярных внешних библиотек, чтобы помогать нам автодополнениями и не ругаться о незнакомых функциях и объектах. Путь к этому файлу всегда задается относительным путем, я не нашел возможности решить это как-то более изящно.

///<amd-dependency path="jQuery" name="$" /> — явно говорит компилятору, что в зависимости модуля нужно добавить jQuery и в аргументах функции передать его как $. Компилятор не понимает структуру конфигурирования RequireJS, потому это способ объяснить компилятору: «Доверься мне, у меня при помощи алиаса „jQuery“ будет загружена нужная библиотека, просто добавь эту строку в зависимости и объяви её для функции аргументом ’$’». Чуть ниже я приведу пример, что же будет сгенерировано.

///<amd-module name="specialName" /> — не часто, но встречается случай, когда модулю нужно дать конкретное имя, (а не просто путь к нему как значение по умолчанию, которое можно даже не указывать), для этого предназначена эта конструкция.

Следующие две строки импортируют один интерфейс и два класса. Да-да, я помню, что уже считается плохим тоном именовать интерфейсы с префиксом I, здесь это сделано для наглядности.

export class Something { .. } — модуль должен что-то вернуть.

Пути, которые используются для импорта — это отдельная тема для разговора. Как сказано выше, компилятор не понимает конфигурации RequireJS и сам не содержит в себе настроек базового пути (по крайней мере, в версии 1.8.0 этого еще нет). У меня работала без проблем такая конфигурация: RequireJS был настроен на папку js (basePath: "js/"), с которой на одном уровне лежал конфиг компилятора, то есть classes/ на самом деле относительно tsconfig.json были js/classes, но компилятор отлично распознавал это. В настройках компилятора есть опция rootDir, эта опция указывает точку отсчета для всех импортов в коде. Так вышло, что мы эту опцию каким-то образом пропустили.

Обратите внимание на сам класс. В нем использованы оба интерфейса как типы, и создается экземпляр класса.

А теперь посмотрим на результат генерации JS-кода:

define("specialName", ["require", "exports", "jQuery",
    'classes/interfaces'],
    function(require, exports, $, interfaces_1) {
        "use strict";
        var Something = (function() {
            function Something(options) {
                var x = new interfaces_1.Modes();
                this.toolbar = null;
            }
            return Something;
        } ());
        exports.Something = Something;
    });

— Модуль имеет необходимое имя;
— jQuery импортируется через алиас,
— Импортируется то, что было реально использовано.

Последнее особенно важно для поддержания структуры кода. Вы описываете нужные типы и интерфейсы, импортируете в свой модуль много зависимостей, а в итоговый JS попадет только то, что реально используется. А именно те классы, чьи экземпляры создаются (через new или вызываются как функция) или если вы используете класс для сравнения через instanceof. От таких модификаций обычного JS-кода TypeScript-код начинает походить на Java или C# в вопросе многословности, но это существенно повышает читаемость кода.

Более того, если убрать строчку this.toolbar = null;, то итоговый класс потеряет это свойство полностью.

exports.Something = Something; — демонстрирует один из не самых популярных методов экспорта из AMD модуля. В документации RequireJS вы можете найти подробности использования универсального модуля exports.

Target

Не стану повторяться, тут все просто — это цель компиляции, какую версию JS вам нужно сгенерировать в результате компиляции.

NoImplicitAny

Эта опция включает предупреждение для случая, когда выведение типов распознает переменную как any, но пользователь не указал этого явно. Например, команда Angular 2 предпочитает держать эту опцию выключенной (false).

Миграция существующего JS-проекта на TypeScript

Простым переименованием файла .js -> .ts вы создаете файл на TypeScript:). Конечно, он вызовет лавину предупреждений в консоли при компиляции, и, скорее всего, на выходе будет ровно тот же код (только с другим форматированием), но это уже начало.

$ tsc --init — создаст базовый конфиг для компилятора.
$ subl tsconfig.json — теперь вам нужно править этот конфиг исходя из реалий вашего проекта.

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

Интерфейсы помогут держать большой проект в здоровом состоянии. Чтобы ознакомиться с функционалом класса, больше не нужно будет рассматривать весь его исходник, переформатировать его под себя... Интерфейсы, строго типизированные декларации полей и методов классов создают, по сути, самодокументирующийся стройный код.

А чуть позже, когда TS-кода станет больше, вы начнете замечать, что ваша IDE начинает активнее вам подсказывать не просто из глобального словаря что попало, а именно то, что нужно (конечно, если в вашей IDE есть поддержка TS).

В большом JS-проекте вы настраиваете компилятор просто компилировать .ts файлы в .js файлы рядом с оригиналом, и это позволит не переделывать сборочные задачи в вашей системе сборки проекта.

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

Конечно, для проектов которые с самого начала разрабатываются или полностью перешли на TypeScript, очень удобно включить в настройках компилятора минификацию и объединение модулей одновременно с генерацией source map файлов. Но пока основная масса кода написана на JavaScript, для вас проще будет производить прямую трансляцию .ts в .js в режиме Один-к-Одному и использовать вашу существующую процедуру сборки проекта.

Внешние библиотеки

Я еще не встречал библиотек, написанных на TS. Нет портов jQuery, Underscore или lodash на TypeScript. Но эти (и многие другие) библиотеки добавляются в проект по умолчанию даже тогда, когда они там и не нужны.

TypeScript поддерживает файлы деклараций типов. Их можно воспринимать как .h файлы из C, но в TypeScript они чуть менее функциональны. Файлы эти имеют расширение .d.ts и никогда не компилируются в .js файлы.

Сообщество уже успело описать большое количество библиотек. Это огромные объемы файлов с декларациями — описания объектов, их методов, функций. Описания содержат и информацию о типах данных для аргументов функций или свойств объектов. Конечно, случаются пропуски, и вы можете найти отдельные функции в библиотеке, которые описаны в документации, но не распознаются компилятором. Это решается собственным файлом деклараций, где вы расширяете базовые описания. Как и в случае с интерфейсами, декларации объединяются простым слиянием.

Вместе с компилятором вы устанавливаете npm-пакет typings — это менеджер пакетов деклараций, который поможет найти нужные заголовки и установить их в специальную папку typings в корне вашего проекта.

Еще недавно эту роль выполнял пакет tsd из проекта DefinitelyTyped. Главное отличие между tsd и typings в том, что tsd хранит все декларации внутри одного большого проекта на github. typings, в свою очередь, использует экосистему npm-пакетов с отдельным реестром существующих пакетов. Подробнее: о typings, синтаксис файлов деклараций.

Поддержка в IDE

Как уже сказано ранее, компилятор предоставляет внешний API для IDE для анализа кода на лету. Различные редакторы используют его по-своему. Приведу лишь знакомый мне (в контексте TS) набор редакторов.

Sublime Text 3. Для этого редактора Microsoft даже написала самостоятельно плагин, который на удивление хорош. Местами, конечно, он упирается в возможности самого редактора — например, все предупреждения относительно строки/токена, где сейчас расположен курсор, выводятся в строке статуса. То есть иногда вы просто не сможете увидеть весь текст ошибки/предупреждения. Тогда придется вызывать консоль и смотреть полный текст там. Плагин вполне хорошо работает, основывая свои настройки на вашем файле конфигурации для компилятора tsconfig.json. Работает умное автодополнение и подсказки по аргументам для функций. Замечу также, что в репозитории пакетов есть несколько плагинов для TypeScript — я рекомендую ставить только один и официальный. Установка сразу нескольких приводит к их конфликтам, и все разваливается.

WebStorm. Эталон и титан среди IDE для front-end разработчиков, имеет, на мой субъективный взгляд, фаната Sublime Text, очень посредственную поддержку TypeScript. Которая к тому же еще и нестабильна — неоднократно замечал зависания фоновой компиляции.

Visual Studio Code. Этот кроссплатформенный редактор от Microsoft, созданный на базе редактора Atom, призван считаться эталонным для разработки на TypeScript. Имеет мощную интеграцию с компилятором — все подсказки и предупреждения доступны там, где их и ожидаешь найти. А недавно в нем появилась поддержка фолдинга для кода... в 2016-м году. Лично для меня этот редактор неудобен очень странной системой проектов и сборок. Но в остальном, редактор, на удивление хорош даже несмотря на то, что он браузерный.

Другие. На главной странице сайта www.typescriptlang.org, посвященного языку, можно найти ссылки на плагины для других популярных IDE.

Следует заметить общую проблему — несмотря на типизацию, интерфейсы и все подобное, рефакторинга в автоматическом режиме нет. Рефакторинг ожидается только с выходом TypeScript 2.1, который состоится когда-то потом.

Что ожидать

Язык и компилятор активно развиваются и завоёвывают популярность. Microsoft, как автор, уделяет языку много внимания и явно делает ставку на него.

О планах развития языка рассказали на конференции Microsoft Build 2016. Приведу несколько пунктов из этого видео кратко здесь.

— Поддержка компилятором JavaScript

Компилятор сможет производить вывод типов на основе jsDoc нотаций (комментарии описания метода/функций), где обычно указывают и тип данных аргумента. Флаг компилятора —allowJs.

— Выведение типов на основе последовательности выполнения

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

— Отказ от null и undefined для базовых типов

Одна из проблем JavaScript в том, что null и undefined существуют во всех типах данных.

Движение «Non-nullable types» приведет к тому, что в TypeScript версии 2 компилятор будет против использования null и undefined для всех типов данных, пока вы сами не укажете, что конкретная сущность может иметь такое значение. Выглядеть это будет примерно вот так: let str: string | null;, только после этого компилятор не будет возмущаться присваиванием в переменную значения null.

Флаг —strictNullChecks будет доступен в TypeScript 2.0.

— Свойства класса в режиме «Только для чтения»

Вероятнее всего, это будет доступно при компиляции в ES5 и выполнено в виде описания только «геттера» для свойства через Object.defineProperty().

— Рефакторинг в 2.1

Функционал рефакторинга, похоже, также будет частью компилятора и его API для IDE. Что ж, звучит разумно, с оглядкой на скорость развития языка, делать рефакторинг частью IDE возможно, но может «выйти боком». Наверно, потому ребята из JetBrains еще не реализовали его для WebStorm на должном уровне. Будем ждать.

Вместо выводов

  • Магии не существует, ну или по крайней мере, разработчики компилятора сюда её не завезли. Часть волшебства строится на столпе описаниях типов данных и структур, другая часть стоит на столпах макросов и шаблонных подстановок с последующим перезапуском анализатора типов данных (generics), и последний столп — вполне простые конструкции кода, в которые разворачивается синтаксический сахар;
  • Внимательное чтение консоли, всех предупреждений должно стать вашей привычкой;
  • ES6, ES2015 — сегодняТеперь не нужно смотреть с завистью на плюшки ES6 или ES2015 — используйте их, просто в качестве цели компиляции укажите привычный ES5;
  • Типизация. Тут можно целые книги писать о пользе строгой типизации. Если очень коротко — большим проектам она нужна как воздух;
  • Абстрактные классы и интерфейсы. Если по какой-то причине вы не писали на языках программирования, отличных от JavaScript, то вам обязательно нужно расширять кругозор, дабы прочувствовать мощь и полезность этих концепций;
  • Синтаксический сахар. Тут даже комментировать нечего — очень много приятных мелочей;
  • Typings — молодой и еще один пакетный менеджер в наш дурдом;
  • Any — неминуемое зло, которое необходимо для старых проектов, еще не перешедших полностью на TS (а, скорее всего, этого не случится никогда), ну и грустная возможность отстрелить себе ногу для ленивых;
  • Целостность и полнота документации еще оставляет желать лучшего;
  • Экспериментальные конструкции вроде декораторов очень заманчивы. Но пока они не войдут в стандартный функционал, они слишком опасны для широкого применения.

В этой заметке я намеренно проигнорировал вопрос запуска TypeScript непосредственно в браузере, потому что считаю это безнадежной затеей даже на время девелопмента — компиляция в браузере происходит ощутимо медленнее, чем в консоли и просто раздражает.

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

70 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

бачу по коментарях, що компілятор для JS розробників це щось страшне і непотрібне. І більшість апелювань — для маленького проекту не потрібен. Я б сказав що це діло звички на 100%. Якщо ви звикли самі перевіряти імена змінних, рядок до рядка або копіпастою я думаю багато часу це буде займати тільки на великому проекті, і це правда. Інша річ коли ви звикли працювати з компілятором — патерни набору коду міняються сильно — спочатку пишемо потім компілюємо, нічого не перевіряємо якщо компіляція успішна. Одного разу звикнувши до компілятора відмовитись від нього дуже важко.

Не страшне, але дійсно не потрібне. Бо можна приміняти інші підходи в розробці, щоб досягати гарних результатів. Наприклад FRP. Там компілятор нічим не допоможе, бо потік виконання команд ситуативний та виникає на момент виконання коду.

Олесандр Шпак вірно підкреслив


Не страшне, але дійсно не потрібне.
Є два табори JS розробників, ті що пишуть у стилі звичному для Java, PHP, C# та інших мов без асинхронності по замовчуванням та іншою моделлю ооп. А є ті що пишуть у саме мови стилі JS.

Я належу до другого табору, як більшість розробників що притримуються думки підкресленої у цьому комменті. Ми не апелюємо до маленьких проектів, просто на них легше пояснювати, на великих проектах пояснювати треба теж саме, тільки для значно більшої кількості коду.

Ми не говоримо що строга типізація та компіляція погано, це добре, особливо добре для, як зазначив вище, «Java, PHP, C# та інших мов без асинхронності по замовчуванням та іншою моделлю ооп». Це дуже вдала думка для вирішення проблем, в вище зазначених випадках мати такий інструмент.

Основний аргумент у захист JS стилю коду, це те що більшість людей першого табору, взагалі невірно програмує на ньому, до JS небажано застосовувати розповсюдженні паттерни у їх класичному вигляді. Але нас не слухають, більшість досвідчених спеціалістів вважаю що JS стиль == функціональний стиль, на справді це ціла низка прийомів та засобів, характерних лише для асинхронного програмування та ряд правил, для використання розповсюджених паттернів.

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

А потім буду розробляти більш складний драйвер, і знову зроблю його сам, і використаю при цьому ті прийоми до яких звик. А потім захочу бачити якісь речі, класичні саме для використаного стилю коду, їх не буде, але хтось з часом їх зробить.

І тут прийде людина що тільки драйвери і пише, покрутить пальцем і скаже «а на фіга ти так робиш? для написання драйверів це не потрібно, тут інші умови». Я можу його послухати, а можу ні. В першому випадку мене підтримають розробники драйверів, у іншому розробники що теж пишуть драйвери у не класичному для драйверів стилі, бо їм зараз не вистачає інструментів.

Отож підкреслю думку ще раз, строга типізація та компіляція дуже корисна річ, і дуже класна насправді, вона дійсно потрібна для JS написаному у стилі класичному для більшості мов.

Основний наш тезис не «TypeScript поганий», наш тезис — «не пишіть на JS у класичному для мов без асинхронності по замовчуванням та іншою моделлю ооп стилі»

Строга типізація — це в першу чергу всього лише спосіб передати статичному аналізатору коду додаткову інформацію. Підкажіть, будь ласка, чого саме я не розумію в тому класичному саме для JS стилі, який ви описуєте, що не уявляю, як користь від можливості зробити більш строгий статичний аналіз залежить від того, в якому стилі пишеться код.

Та без питань, класичний приклад що зазвичай приводжу студентам у учбовому центрі при нашій студії.

Наприклад візьмемо доу, є коментування поста. При публікації комента, треба надіслати автору оригінального поста повідомлення про коммент.

У класичній мові (Java, PHP, C# та інших), публікація поста викличе функцію відправки повідомлення.

У JS коментування створює подію «новий коммент», і на цьому вся логіка контролера завершуеться. Але існує інший контроллер що слухає подію і робить розсилання повідомлень. Таких слухачів може бути безліч і логіка в данному випадку нагадує дерево а не єдиний ланцюг викликів.

А що роблять більшість новачків у JS? намагаються як і раніше программувати ланцюгом, звісно їм не зручно, бо класичні інструменти пристосовані зовсім до іншого.

Як на мене, це навпаки дуже вдалий приклад для демонстрації переваг строгої типізації. В двох різних (а може і у безліччі) рознесених в коді місцях утилізуються дані певного типу, і зручно задекларувати, який саме вигляд ці дані повинні мати, і в разі чого чітко отримати повідомлення про те, що вони трактуються у неочікуваний спосіб, ще до того, як код буде виконаний. А те, ланцюжки викликів методів у тому коді, піраміди колбеків, FRP чи евент брокери — це ж не стосується наявності чи відсутності строгої типізації.

А в чем проблема проверки типа данных в JS? Тип данных выступает часто и свичером, для расширения интерфейсов.

Это наоборот будет мешать.

Умные дядьки когда-то давно ушли от TypeScript в сторону JavaScript.
Теперь у нас есть куча новичков и реклама майкрософтом TypeScript.
Честно... TypeScript не поможет ровности рук, а только добавит еще одну технологию, которую придется потом поддерживать.

Вы с чем-то путаете, TS слишком нов, чтоб «умные», как вы говорите, «дядьки», когда-то давно могли уйти от него.
Да, TS не поможет кривым рукам, тут я согласен полностью. Но об этом в статье нет ни слова.

TypeScript официально релизнулся в 2012 году, но его разработка велась еще до JS. Собственно JS и появился как лучший аналог TS.

Если вы говорите про ES6/ES7 тогда понятно о чем вы. Но это не отменяет важности строгой типизации.

Нет, я говорю о времени когда JavaScript еще не было, погуглите объяснения создателя JS зачем это было сделано. Что до второго, не вижу особой важности строгой типизации в контексте JS.

JavaScript First appeared — May 23, 1995; 21 years ago
Это из википедии... Как бы, TS это именно надстройка вокруг JS, а не наоборот. TS придумали, что бы попытаться закрыть хотя бы часть дыр в спешно придуманном JavaScript. Но не наоборот.

В том то и дело что нет, JS это то что спасло нас от TS в свое время. В 2012 году был официальный релиз, но о TS было известно и до этого. Погуглите ту тему что я рекомендовал постом выше.

Все же вы путаете начало с концом. Наверное, вы путаете с VBScript и JScript (оба от Microsoft года 96го). Но это были совсем другие языки.
TypeScript — это транспайлер в классический JavaScript. При этом (блин, повторяю статью) любой JavaScript код по умолчанию, является синтаксически валидным TypeScript-кодом.
Там выше есть ссылка на первую часть статьи, я там упоминаю про это.

Выше уже дважды писалось что конкретно надо гуглить для пруфа, но вы правы, спутал его с VBScript. Мы могли бы выяснить это раньше.

Тем не менее,

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

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

Если вам мало защиты вашего или не вашего API по типам данных и интерфейсам при использовании, то дальше вам уже ничего не объяснить в разумных временных рамках, простите.

Навіщо писати щось, що треба потім ретельно захищати? Приведіть приклад коду, який неможливо зробити інакше окрім строгої типізації. І не забувайте, що друге слово в назві мови — «script», що в найближчому перекладі буде «сценарій». Це вже мусить підказувати спосіб використання даної мови програмування.

У меня нет такого примера меньше проекта на многие десятки мегабайт чистого кода, который разрабатывался не одним поколением девов, где первые авторы уже и из компании давно ушли, а документация не поспевала за бизнесом...
Я достаточно многословно в двух частях описал Зачем это все нужно. В первой части есть подробное объяснение. Перечитывайте до полного просветлени. Спасибо за внимание.

Т.е говнокод? строгая типизация необходима чтобы поддерживать говнокод?

О чем вы? где связь? вы вообще в своем уме? или больше 10k строк кода вы проектов не видели? Бывают приложения сложнее бложика на коленке которые пишутся вполне профессионалами своего дела. И вот профессионалы, в отличии, видимо от вас (уж простите), обычно понимают, что они люди и они и их коллеги могут ошибится — не доверяют себе и другим.

Предлагаю закончить этот тролло-ло трёп. Мне больше нечего вам сказать.

Ну видел к примеру в процедурном программировании. Что это за код такой, в котором нельзя на 10к строк кода, хоть немного изолированной функции для демонстрации преимущества строгой типизации найти? Ответ выше — говнокод.

в linkedin профілі можна подивитись спеціалізацію Олександра: php, nodejs, js. Можливо нема з чим порівнювати — не доводилось працювати з stronly-typed кодом щоб оцінити переваги. У мене наприклад перші пів року на JS після stronly-typed мов просто не було слів — тільки фейспалм і матюки. Але потім звик)

Почему же, я нигде не писал что это плохо. Один извесный джава скриптер, когда-то сказал «Создавая абстракции, помните что вам придется с ними работать». Именно эту концепцию я и озвучил

TypeScript не поможет ровности рук, а только добавит еще одну технологию, которую придется потом поддерживать.
JavaScript не создает для меня сложностей, требующих его замены. Перейдя на TypeScript, я понимаю не нативность этого решения.

В то время как комментатор выше настаивает на TypeScript как лучшая замена JavaScript, приводя в аргументы

любой JavaScript код по умолчанию, является синтаксически валидным TypeScript-кодом.

Но мы же понимаем что создавать неоправданную абстракцию это чревато, и то что в абстракция понимает нативный JS, это как раз не странно, но наоборот то нет.

Потому я попросил привести пример, где это преимущество видно, чего и не получил. Этого же попросил еще один человек, примера так и не поступило.

О чем вы? где связь? вы вообще в своем уме? или больше 10k строк кода вы проектов не видели? Бывают приложения сложнее бложика на коленке которые пишутся вполне профессионалами своего дела. И вот профессионалы, в отличии, видимо от вас (уж простите), обычно понимают, что они люди и они и их коллеги могут ошибится — не доверяют себе и другим.
Предлагаю закончить этот тролло-ло трёп. Мне больше нечего вам сказать.
Ответ на вопрос человек давит на доверие и старается завершить разговор.

Это этапы нашего разговора и я по прежнему с удовольствием получу новые знания касательно данного вопроса.

Слухайте, не треба нам розповідати про «складні проекти». Думаєте ви один їх писали? Подумайте краще над тим, чому іншим не заважає відсутність строгої типізації в JS

Навіщо мені проникатися вашими проблемами? Можливо ви щось робили не так? Можливо ви вимагали від мови того, до чого звикли, а не навпаки? Існують сотні патернів розробки, але ви вибрали той, який складно робити на JS без додаткових хаків та танців з бубном. Якщо мені б сказали, що ти будеш використовувати мову програмування, де немає строгої типізації, я б сказав «Ок, зрозумів, треба розробити той підхід, в якому це буде норма й не впливати на роботу системи в цілому» а не «Треба із JS зробити мову зі строгою типізацією»

Последняя попытка.

Обсуждение радостей типизации вообще должно происходить в комментах к первой части. Но да ладно, сцепились тут.
Ни на какое доверие я не давлю. Я пытаюсь донести одну простую истину — вы не заметите мега-профита на маленьком примере кода. Этого не будет. Любой кусок разумного размера который бы я тут привел, вы бы назвали простым, которому не нужны типы и интерфейсы. Вы бы сказали, что все дело в правильных именах для аргументов, функций, классов, объектов, а потом еще бы добавили контрольный «ну и doc-заголовки к методам подробные пишите».

Это все хорошо и мне бы пришлось с вами согласится. Но лишь на том маленьком примере, если бы я поддался на правокацию.

Как правильно где-то было подмечено, TS все же не язык строгой типизации, он язык статической типизации. Как я писал, у вас нет проверки типов в рантайме (сверх той, что есть в JS). У вас есть только этап компиляции, где компилятор может сравнить ваши заголовки с вашим использованием и если вы где-то допустили вольность — он просто предупредит вас об этом.

Типизация тут, это все же не сложения number + string. Нет. Это детские болячки, впрочем, за которым тоже нужен глаз, да глаз даже в коде у бывалых разработчиков.

Вам дана возможность описывать интерфейсы и классы и использовать их как новые типы данных для той эе статической типизации. Это дает вам возможность переносить сложные структуры между модулями не заботясь о точности copy/paste «а правильно ли я ту структуру опций на over30 полей перенес для вызова?». Вы создаете новый тип данных (пусть и только на этап компиляции) и просите в явном виде компилятор «вот в том модуле, я создал монстра типа А, в других пяти модулях, мне нужно его не спутать с модулем Б и хочется быть уверенным, что я ничего не забуду». И вы не забудете — IDE вам подскажет интерфейс вашей структуры, ведь у неё есть нужные данные, она их не угадывает из глобального словаря, если через месяц вы внесете правки в эту структуру в главном модуле, компилятор (или IDE) вам четку укажут, какие связи у вас сломались, где следует посмотреть? Да, тот же результат достижим с тестами, но человек может пропустить что-то и какой-то параметр не добавить в тесты, а машина нет.

Теперь про большие проекты.
Когда размер проекта и длительность его разработки огромны в динамическом мире школьного JS и это не долгострой с сорванными сроками, а инкрементальное развитие большого продукта. Вы, как бы гениальны вы не были, столкнотесь с плавающими багами, несмотря на все горы юнит тестов, интеграционных, селениум-тестов. Все равно, в большой системе, как бы стройна она не была, рано или поздно заводятся демоны. Уж простите за такой образ. Команда сталкивается с проблемами в старом коде, где связь внутренних потоков данных может быть более чем сложной и понять по options что же это за options становится довольно трудно, если комментарии профукали еще в том году, так тогда не было практики code review или релиз уже демился. Так бывает, к сожалению и причин может быть много.
Или в команде появляется новый разработчик, который может в спешке наставить кастылей и бизнесс это со скрипом продавит через code review. А потом галочка о рефакторинге этих костелей может просто затеряться в бездонном беклоге очередного спринта и...
TS для меня в таком случае, это просто дополнительный уровень защиты — код получается строже, декларативней и понятней даже новичку. Я пишу интерфейсы к сложным структурам и классам, я пишу абстрактные классы и могу быть уверенным, что их не вызовут напрямую сломав мои задумки. Когда за вами есть автоматический контроль, то сложнее писать говнокод. Вспомните первые ощущения, когда вы впервые подключили к проету jsLint или jsHint. Вы помните, то вдохновение и ужас от того, что вас принуждают соблюдать правила и писать как минимум синтаксически не ужасный код?

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

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

Конечно, если вы гений, если вы никогда не ошибаетесь и с вами работаю ваши клоны, если бизнес возле вас ходит на ципочках и вам не хозяин, вы вольны писать исключительно чистый код с превосходной документацией и сразу со 100% покрытием тестами, то тогда я склоняю перед вами голову — TS вам точно не нужен и простите за впустую потраченное время.

Длинопост, но я прочитал. Так проблема в глобальных переменных и интерфейсах? И судя по футеру, в TS нет нужны в доках и покрытию тестами?

Все що ви тільки що написали для мене звучить так: «Ми повісили собі на ногу гірю, і тепер намагаємося придумати спосіб як з нею існувати». Підказки та запитання із натяками я вже задавав. Ви проігнорували їх.
Ви обрали шлях «класичного» ООП в мові, де воно реалізовано із нюансами? Добре, тоді чому ви тепер скаржитеся на недоліки мови? Навіщо шукати синтетичні замінники? Ви ввели абстрактні класи та декларації складних структур, а тепер обкладаєтеся тестами, бо не впевнені, що воно буде й надалі існувати? Так до чого тут типізація, строгість мови чи ще щось?
В мене немає ваших проблем, хоча проекти великі та їх було багато. Бо всі вони побудовані на інших принципах. Я використовую для структур даних XML або JSON, для бізнес-логіки FRP, а замість модулів чи об’єктів — темплейти. Інша декомпозиція проекта взагалі. А ще я люблю підхід «працюй або мовчи», коли код виконує корисну роботу тоді, коли може, а якщо щось пішло не так, то й фіг з ним, йдемо далі. Це просто доводило до білого каління одного з розробників, який дуже любив підхід, що код мусить обробляти всі ексепшини, інакше смерть. Так от смерть дійсно буде, тільки проекту. А мій код працює роками, навіть із багами, які закладені в дизайн.

Проекты бывают разные, как и задачи.
Отстаивание с пеной у рта своих привычных галер, говорит лишь об упорности и не желании развиваться «Ведь оно и так работает, верно?».
А вот команда, где я перевел разработку на TS через пару месяцев открыто подтвердила, что стало лучше/легче писать новый код и поддерживать старый, когда отдельные, особо упоротые модуля переписывались на TS и становилось всем лучше. Было замечено даже повышение стабильности нового функционала, т.к. компилятор вполне вылавливал мелкие нестыковки между модулями разного авторства еще даже до интеграционных тестов.

В общем, не верите, не убедил я вас — ну и пусть. Я попытался донести свои впечатления от TS. Видимо плохо получилось, плохой писатель.

Попробуйте и сформируйте собственные впечатления, не по моим писулькам и моим аргументам, а на реальном своем коде. А то поливать помоями абстрактного коня в вакууме все умеют.

Я буду рад прочесть подобную статью от того кто из вас реально попробовал и ему не понравилось.

Навіщо розвивати зайві або шкідливі навички? Краще розвиватися там, де ще море всілякого цікавого та незвіданного. Там де є можливість створити щось дійсно цікаве. Вам варто вирватися із закритого кола ООП та почати вивчати інші підходи та паттерни в розробці. Ви зрозумієте, наскільки ваші «проблеми» міфічні.

Причем здесь ООП вообще? Или вы считаете, чо на TS нельзя финкциональщину писать?

Почему джависты могут генерить приложения одним только автокомплитом? А почему в JS это невозможно? Потому что один строго-типизированный, минимум динамичесности. А в JS, пока вы реально не запустите код, у вас нет никаких ответов ни о чем дальше 10 строк от курсора. В большой кодовой базе это становится проблемой не только IDE, но и всех разработчиков. Интерфейсы, обстрактные классы — это все про строгость декларации. Вам и IDE сможет помочь и компилятор на ошибки укажет. jsDoc не ответ, т.к. никто их не пишет толком и у каждого свое ощущение красиво/правильно оформленного комментария; впрочем и синтаксис слишком ограничен, чтоб на что-то надеяться.

Но «патерны», «подходы», «каждую неделю новый революционных фреймверк», сходил в отпуск без интернета на месяц — вон из профессии, ты безнадежно устарел, поезд ушел.

Похоже, проблема в другом — в мире JS вообще не принято смотреть в сторону других яп. Тесный ограниченный мирок хипстеров с leftpad’ами наперевес.

«Мы все дыры во всех бочках заткнем jQuery и Express’ом».

Но тогда все понятно.

ООП до того, що вимоги будь якої типізації витікають саме з класичної школи ООП.

IDE driven development — це не мій шлях. Велика кодова база — це як раз наслідки ООП. В FRP вона абсолютно іншою буде, бо повторне використання коду ну дуже сильне. І IDE там не помічник в будь якому випадку.

Проблема JS в тому, що в нього як раз прийшли із інших МП, із своїми уставами, і почали робити із нього Java, Python, Ruby та інше, хоча просто треба було поміняти власне мислення. Це скриптова мова, найближчий родич — bash, а не Java.

Говоря про ООП и типы, вы спутали корову с яйцом. Даже в чистейшей функциональщине, для мьютабельной константы, компилятору нужно понимать, как работать с памятью — обрабатывая 42 выделить 2 байта (в простейшем случае) под строчное представление двух символов или обойтись одним байтом.

Говоря про IDE driven development и большую кодовую базу — вы опять сравниваете горячее с красным и путаете причину и следствие. Генерация кода и автокомплит возможны там, где известна структура, где она предсказуема статически.
Читая Что нового в WebStorm мы то и дело видим Улучшение поддержки конкретного фреймверка, тогда как тот же список для java IDE редко имеет подобные пункты. Все дело в костылях — для популярных фреймверков IDE имеет пресеты и внутренние подсказки анализатору кода. Вот только шаг в сторону по структуре проекта или превышение порога сложности и он сливается чуть менее чем плностью. Потому я IDE и не использую.
Откровенно огромные абстракции, множество слоев и фремверков в java-проекте вынуждают иметь автокомплит и интеллектуальные сниппеты для ускорения процесса разработки.

А проблема JS, на мой взгляд — в среднем возрасте JS-кодера, который со студенческой статьи пороху не нюхал, а нашел себе «простой» яп и jQuery. Это уже потом он начинает понимать куда попал, но уже поздно, уже middle’а получил и ЗП, он и продолжает гнуть свою хипстерскую линию и плодить треш в npm.

Да, я пришел из прикладного программирования через бек-энд в JS-мир. Да, у меня сильно зашоренные глаза несколькими другими, в том числе и старшими яп. Да, глаза режет от того безумия, который в JS мире считается «и так работает, как-то прорвемся». Но если не развиваться, не пытаться что-то именить, то и все эти статьи и треды троллинга, через 4 месяца после публикации статей, — бессмысленная трата электричества и нашего времени.

Я повторюсь в очередной раз — попробуйте, а потом опишите результат. Тогда будет какой-то смысл в диалоге.

Ох нафлудили, Anton Artyukh, это уже фарс, с одной только фразы

Причем здесь ООП вообще? Или вы считаете, чо на TS нельзя финкциональщину писать?
понятна правота слов Олександра Шпака. JS это ооп язык, полиморфизм, наследование и инкапсуляция которого существуют в соответствии с местом где он используется.

Вы говорите

А проблема JS, на мой взгляд — в среднем возрасте JS-кодера, который со студенческой статьи пороху не нюхал, а нашел себе «простой» яп и jQuery.
Но уверен вы не умеете даже правильно класс получить без jQuery.

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

О забомбило-то как, а? Видать угадал))

Ха-ха, типичный холивар в стадии перехода на личности :)

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

Ранее вы говорили

Наверное, я скучаю по более строгим яп, что были в моей парктике.
В ваших навыках, кроме JS присутствует только Python. Я тоже работал с пайтоном, потому знаю что в пайтоне динамическая типизация, утверждение выше уж очень воздушное и это только один из ляпов.


Вам хочется самоутвердится, а я ищу знания.

Вы так лихо проанализировали мои профили, не допустив мысли о их неполноте. В вашем профиле нет пайтона, но вы с ним работали. Но да ладно. Не про лично нас разговор.

Это вы усомнились в моих знаниях на ровном месте, не я в ваших. Приношу извинения, если не так понял, хотя по прежнему уверен, что понял правильно.

Во всем этом холиваре вы и Александр, упорно игнорирует факт — вы не пробовали TS. Вы не пробовали написать, что-то не простое что бы просто посмотреть А как оно вообще?

Вы тянетесь за новыми знаниями в виде сиюминутного примера, киллер-фичи, при виде которой вы могли бы воскликнуть О как круто! Как я раньше жил без этого? Или Вот точно это не полетит, это трата времени, нам не по пути, закрыть табу и забыть. Но так не бывает. Это всегда процесс. И я не могу залезть вам в голову и вложить туда свою картину мира. Вы рисуете её себе сами. Так нарисуйте и поговорим по делу. Я написал эти статьи после нескольких месяцев работы с TS, уверен, это отражено в тексте. Потому, я не просто примерчики из документации повертел. Хватит трепа и сведения всего к примитивным вопросам.

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

Вы можете сказать как в нативном JS получить имя класса.

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

Таки зря извинился.
Нам с вами не о чем разговаривать. Мне безумно жаль потраченное на вас время. Прощайте.

Любопытно.

компилятору нужно понимать
Компілятору? Чисті компілятори бачив тільки на C та C++. Все інше або інтерпретатори, або байткод ВМ (що теж не чистий компілятор).
Генерация кода и автокомплит возможны там, где известна структура, где она предсказуема статически.
Дякую, кеп! Раджу вам попрацювати із XML та FRP. Можна навіть водночас. Суто для розвитку.

І ще раз про TS. Мені він як до сраці карі очі. JS повністю виконує всі задачі, то навіщо мені ще один рівень абстракції?

Из того, что наблюдаю лично — Google многие проекты переписывает на TypeScript. В частности, вся актуальная инфраструктура для разработки на Polymer уже пишется на TS.
Так что не майкрософтом единым...

Переписывать — нет, вести разработку да. Гугл заключил договор с майкрософтом, это не было решением программистов, это решение маркетологов.

а можно конкретный пруф?
Нет, я понимаю, современными IT-гигантами рулят маркетологи, но все же. Я о таких договорах ничего не слышал, хоть и допускаю их возможное существование.

channel9.msdn.com/...Events/Build/2016/T669-R1
единственное, что нашел (доклад не опубликован).

О, это одна из самых знаменитых договоренностей, та самая что внедрила в гугл TypeScript.
Пожалуйста не плодите ветки.

Выступление было 31го марта 16го года, Angular2 разрабатывается заметно дольше и это опять же просто очередная реклама TS, но под соусом гугла.

По прежнему не вижу конкретного прува.
З.Ы. весь гугл перечитывать вашему запросу у меня времени нет. А изночально вы это высказали как 100% утверждение, будто в соседней вкладке у вас скан договора открыт.

Антон, вы еще в гугл позвоните и их скан попросите.

Впрочем, даже если договор и имеет место быть. Какая разница? У меня своя голова на плечах, мне нравится этот язык, он развивается в нужную сторону и у него уже есть место в экосистеме JS. Если по какой-то причине он не устраивает вас — это ваши сложности. Хотя ничего конкретного вы так и не высказали против языка. А игнорировать язык можно и не раздувая при этом тред в комментариях о том, что некие умные дядьки когда-то проигнорили, к тому же промазав вообще с тем, что именно они проигнорировали.
У меня все.

О чем и было сказано мной.

Честно... TypeScript не поможет ровности рук, а только добавит еще одну технологию, которую придется потом поддерживать.

дякую, цікава стаття.

Многие .ts файлы не поспевают за обновлениями, кстати. Столкнулся с этим при разработке

а в WebStorm были только проблемы зависания компиляции? или какие еще траблы?

Нет рефакторинга в виде который ожидался для группы полностью описанных и структурированных TS-файлов.
Автокомплит беднее чем от плагина в Sublime Text.
Собственно, я жду именно рефакторинг в WebStorm. Без него, этот тормознутый трактор мне не нужен.

эххх... ну это главный минус тайпскрипта тогда в моем субъективном восприятии

визуал студио круто конечно, но не у всех винда, и саблаймом не пользуюсь

Visual Studio Code — это отдельный продукт на базе гитхабовского редактора Atom. На разработку большого проекта, наверно не подойдет, скорее даже сдохнет в процессе переваривания, но вот как proof of concept — очень даже отлично.
И почему вы так смело отнесли это к минусам тайпскрипту? Основываясь на моем предположении относительно рефакторинга через API компилятора?

пркиольно, я как то прочитал на автомате VS, даже не знал что есть VS Code

для меня важно удобная работа с языком, а это и среда. и да, раз уж использовть типизацию то хотелось от среды (IDE) получить удобный рефакторинг, так как в джс он везде через одно место, что мне не нравится =(

Visual Studio Code

Начал пользоваться с полгода назад (может даже больше) для работы над клиентской частью (EmberJS) — сейчас очень им доволен ... мне, субъективно, нравится больше Атома и быстрее ...
На большом проекте не сдохнет ... даже удивила вменяемая поддержка Vim mode ...
Сейчас пробую (как горячую воду :) ) TypeScript в процессе рефакторинга проекта (воодушевляет пример движка рендеринга любимого фреймворка, написали на TS полностью — Glimmer2 ) ...

Кстати, не считаю что статическая типизация (в нашем контексте) оправдана для больших проектов только ... хотя, возможно, сказывается долгое время общения с языками со статической типизацией (но не только — есть и Ruby, Groovy etc.)

typescript нинужон

Пожалуйста, не откапывайте эту стюардессу, почитайте треды выше — там достаточно жести и есть практически все аргументы во все стороны и против, и за, и вширь, и вкось...

Спасибо за обе статьи.

amd-dependency
штука странная — не добавляет зависимость при компиляции

Зависимость не участвует в проверках типов и прочем анализе, но добавляется железно в код as is. По простому утверждению «не работает», сложно определить, что не так в вашем случае.

в моем случае все зависимости добавляются в js, но socketio-client все никак не хочет добавлять

Подписаться на комментарии