Чи використовуєте ви TypeScript в production?

Колеги, а використовуєте ви TypeScript в production? Якщо так, то що вас схилило до його використання? Яка продуктивність тепер порівняно з JavaScript/ES6? Яка була learning curve? Якщо принципово ні, то чому? Що було showstopper-ом?

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Script# и TS разного класса решения. но я думаю вы и так сами это знаете.

Виявляється, починаючи із версії TypeScript 2.0.0, тепер можна ставити типи даних точно в такий же спосіб, як ми ставимо й інші залежності для нашого проекта:

npm install --save @types/lodash

В такий спосіб ми ставимо визначення для lodash (тепер всі типи зберігаються в каталозі node_modules/@types/...) і зберігаємо залежності у packege.json. Заліковно! =)

The above command installs the scoped package @types/lodash which TypeScript 2.0 will automatically reference when importing lodash anywhere in your program. This means you don’t need any additional tools and your .d.ts files can travel with the rest of your dependencies in your package.json.

From TypeScript 2.0 is now available!

Так, суперово! Дякую згадали тут про це. Мене найбільше в другій версії заінтригував strictNullChecks. Думав прощавайте runtime exceptions. Але ж ні. Далі я зясував ось таку річ github.com/...t/TypeScript/issues/11238. А тоді ось таку stackoverflow.com/...s-does-not-narrow-down-un. Excitement минувся...

Багатьох розробників може зацікавити наступна фіча TypeScript:

export type TabName = 'unread' | 'readLater' | 'read' | 'favorites' | 'trash';

Таким чином ви оголошуєте тип даних TabName і перераховуєте допустимі варіанти. Тепер в змінну tabName не передаси невірного значення:

let tabName: TabName; // Кажемо який тип допустимий
tabName = 'unread' ; // Ok
tabName = 'uread' ; // error TS2322: Type '"uread"' is not assignable to type 'TabName'.

Схоже, що опитування за TypeScript на продакшені можна плавно перевести на опис «з чого почати знайомитись із TypeScript».

Найперше, поставте собі typings — це пакетний менеджер TypeScript, він шукає, ставить та видаляє файли, в яких є визначення типів даних зовнішніх JavaScript-бібліотек.

sudo npm install typings --global

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

Наприклад, знайдемо TypeScript-визначення для JQuery:

typings search jquery

Бачимо, що в колонці SOURCE указано dt — тобто це визначення знаходиться у бібліотеці DefinitelyTyped, його треба ставити з флагом —global.

Заходите в кореневий каталог вашого проекта, де ви хочете писати код з використанням JQuery, вводите:

typings install dt~jquery --global --save

Зверніть увагу на префікс dt~ тут треба прописувати SOURCE, звідки ви хочете поставити певне визначення. В даному випадку це dt.

Ці файли визначення будуть ставитись в каталог typings, звідки їх вміє читати, наприклад, VS Code, Webstorm...

І все, це все що треба зробити, щоб вам стала доступна практично повна документація по JQuery до будь-якої функції, завдяки якій можна тепер знати:
— які є варіанти сігнатури виклику даної функції (тобто, якщо передавати функції два параметри, то вони повинні мати такі-то типи даних, якщо три параметра — то інші типи і т.д.)
— яке значення повертає дана функція по кожному із варіантів сігнатури.
— коментарі по кожному із варіантів сигнатури
-...

Тепер у будь-якому місці вашого проекта, створюєте файл із розширенням .ts, пишете долар (знак JQuery), ставите крапку і вам видається увесь список властивостей об’єкта JQuery...

І такі визначення є мабуть для усіх найпопулярніших бібліотек, в тому числі для Node.js, Express.js, React.js, Backbone.js, Ember.js...

Бывает, правда, что менее популярные JS библиотеки или контролы в typings не представлены. Для js-grid, например, пришлось самому писать .d.ts файл.

Ні, не використовую, замість нього — ClojureScript

Хм, але ж Clojure динамічно типізований :-)

Це погано? :p

Він «правильно» динамічно типизований, тому проблем від цього меньше, ніж бенефітів. До того ж це лісп :)

Та ні, класно, просто Ви вжили «замість» от я і подумав як це динамічна мова може замістити штуку яка лише те і робить що типи додає :-). Я б тож залюбки щось юзав функціональне, типу Elm, бо я полюбляю типи, але ж як це клієнтові продати? Після мене ж клієнту буде важко знайти девелоперів на Elm...

але ж як це клієнтові продати?
ну по-идее продать можно и скомпилированные Elm’ом js-файлы, и клиенту не обязательно знать, чем оно было скомпилировано)

Писал проектик на Angular 2 + Typescript. И как-то не зашло. Теряется динамика JavaScript, как по мне.

Мабуть ви «із пушки стріляли по горобцях», в такому разі дійсно краще рогатка підійде...

Раз покищо ніхто не пише за продакш, то напишу за свій досвід використання для розробки.

Раніше приглядався до TypeScript через те, що Angular 2 повністю написано на ньому. Для мене стало цілим відкриттям, що статична типізація, яку пропонує TypeScript, може дуже суттєво спростити розробку. Разом із тим, це було парадоксально: начебто коли розробнику приходиться писати додатково типи даних, то це його має більше напрягати... і як я думав, це всього лиш допоможе при транспіляції, але як виявляється — розробник отримує не меншу користь від нього вже на етапі написання коду в IDE.

До речі, рекомендую безкоштовний редактор VS Code, який добре розуміє TypeScript, нові стандарти ES2016 і т.д.

Зараз я не погоджусь працювати без TypeScript, я його використовую як на бекенді під Node.js, так і на фронтенді під Angular 2. Спеціально, без потреби, далеко не заглиблювався у вивченні TypeScript, мінімальні ази можна вивчити дуже швидко і їх вистачить «на довго», а далі — вже по мірі потреби дивитись що і як можна на ньому писати.

Хочете на бекенді працювати з БД і знати на які поля можна розраховувати (коли ще й самої БД може не бути, бо вона ще лише розробляється)? Немає проблем, в якомусь файлі оголошуєте:

export interface IUser
{
  id: number
  ,userName: string
  ,userEmail: string
}

Тепер імпортуєте цей інтерфейс в будь-яке місце, де треба знати перелік цих полів:

import {IUser} from './user';
let user: IUser;
user. // тут ставите крапку, і вам показується потрібний список полів.

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

Інший великий плюс, який не стосується статичної типізації — писати код, використовуючи можливості ES2015, ES2016 вже зараз, і транспілювати код хоч у ES 3. Щоправда, є такі фічі, які не можуть транспілюватись із ES 2016 навіть у ES5, наприклад async/await. Але якщо ми говоримо за Node.js, то більшість із ES2015 вже підтримується.

Я на повну вже використовую async/await:

class User
{
  constructor( private userService: UserService ){}

  async getUserFromDb()
  {
    let user = await this.userService.getUserFromDb().catch( this.errorHandler );
    
    console.log(user);
  }

  private errorHandler(err)
  {
    console.log(err);
  }
}

А шо це за діч з (private userService)? Це Майкрософт винайшов за визначенням не видимі за межами скоупа агрументи функції як поля класу? І як з таким можна жити? Чи це Ви помилилися, використавши () замість {}?

Такий синтаксис використовується для Angular Dependency Injection — мега зручна фіча! В конструкторі ви оголошуєте властивості і їх типи, а DI забезпечує усі залежності.

Тобто наступним записом DI зробить інстанс UserService, і якщо у нього є свої залежності, то він вирішить їх автоматично, і відповідно ви вже можете оперувати змінною userService як об’єктом класу UserService

constructor( private userService: UserService ){}

Для Node.js я використовую їхній аналог як окремий модуль. Це дуже зручно не лише з точки зору вирішення залежностей, а й для тестування.

Я розумію, що з транслятором можна що хош перекласти, але це діч: private визначати в сигнатурі метода. За визначенням в усіх мовах аргументи методу наявні лише в межах методу, і private — це безглуздя. Я користуюся [’userService’, function(userService){}] і маю уявлення про ін’єкцію. Але приклад вище я не розумію )

Мірилом безглуздя для вас є «такого я ніде не бачив»? До речі, в моєму коротенькому прикладі ви зуміли заплутатись? Там же чітко видно, що private userService видима в усьому класі, а не лише в межах методу. Тобто це оголошення для всього класу.

Якщо вам не подобається такий синтаксис, то ніхто не забороняє написати це звичним для вас чином:

class User
{
  private userService;

  constructor(userService)
  {
    this.userService = userService;
  }
}

Инькции тут не при чём. Код

export class Foo
    {
        constructor(private i: number)
        {
        }
    }

транслируется в банальное

(function (Namespace) {
        var Foo = (function () {
            function Foo(i) {
                this.i = i;
            }
            return Foo;
        }());

Классно! Спасибо за интересный фидбек! Теперь появляется надежда что restful apis обретут свой wsdl, когда до слаботипизированых фанатов дойдет что интеллисенс это не просто свистелка, а реально полезный инструмент значительно ускоряющий разработку и порог вхождения, а значит и стоимость разработки.

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

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

Спасибо за совет Александр! Обязательно уточню тонкости терминологии, но я надеюсь вы же поняли о чём я хотел сказать.
Есть возразить что-то по существу кроме «формальных исследований»? Буду рад обсудить! Можем устроить опрос: что проще, посмотреть структуру данных которую подсказывает IDE (нажав точку или стрелочку) или идти искать где же она там динамически создаётся. Многое ведь зависит от того, сколько кода в день вам нужно перелопатить. Если вы сидите над классом неделю — понятно вы выучиваете всё наизусть, но а как же другие коллеги по несчастью, разные там рефакторинги, код ревью, парные программирования, несколько параллельных проектов ...
Тут наверное можно только позавидовать вашим когнитивным способностям которые явно выше среднего в области запоминания больших кусков кода. Я например «середнячок» и большинство моих коллег тоже.

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

Languages are often colloquially referred to as «strongly typed» or «weakly typed». In fact, there is no universally accepted definition of what these terms mean.

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

TypeScript забезпечує статичну типізацію, про runtime типи (тобто динамічні типи) він нічого не знає.

Смілива заява про відсутність досліджень ))). Як раз я цим питанням цікавився і виявляється є. Ось, почитайте анотацію link.springer.com/...10.1007/s10664-013-9289-1.

Якщо маєте час, послухайте інтервью www.functionalgeekery.com/...pisode-55-andreas-stefik з мужиком що як раз займається формальними дослідженнями usability мов програмування. Він там прямо каже у нього є формальні підтверження, що статична типізація підвищує ефективність розробки особливо maintenance. А от порог входа, він каже, напаки вищий у статично типізованих мов. Дійсно, з системою типів ще треба розібратися ))).

Дійсно, з системою типів ще треба розібратися
интересное замечание, раньше не задумывался что это может стать серьёзным препятствием. Если исследования подтверждают — буду иметь в виду и благодарю за ссылку!
Теперь появляется надежда что restful apis обретут свой wsdl,
Инструменты для описания контрактов, генерации клиентов и тестов для REST API существуют уже не один год.

я знаю только swagger.io, подскажите если вы работали с другими, всегда рад узнать что-то новое! К сожалению, единого стандарта как это было с SOAP пока не появилось.

А вы читали холивары а-ля rpc-soap vs rest? Там слаботипизированные фанаты реально жалуются что wsdl нельзя было понять, поэтому мол REST нас всех спас и теперь им всё стало понятно. Люди реально не осознают того, что можно сгенерировать клиент автоматически и изучать API через IDE а не в спец плагинах для браузера создавая запросы врукопашную ...

так многие генераторы написаны вроде github.com/...customizing-the-generator
можно и клиент и стаб для сервера генерировать ...

коллеги пользовались, С# клиент генерировали для API тестирования, а какой вам генератор не понравился? Давайте попробуем какой-нибудь TypeScript hello world API написать, мне интересно что получится. Может какой-то конкретный генератор кривой?

а может вы расскажите что у вас конкретно там не получилось из «самого простого»? Тогда я попробую это сделать тоже и вместе мы может найдём решение! А то мы сейчас с вами нагенерируем списки )) Давайте клиент на C# сгенерируем, выложим на гитхаб и обсудим, если есть конечно желание.

Да, будет здорово если вы это всё хотите описать, реализовать и выложить, я вас морально поддержу!
Так а вы всё-таки скажете что у вас конкретно там не получилось с генератором, чтобы я попробовал тоже? Может я нахожусь в неведении относительно инструмента и он вообще ничего не умеет, а мой коллега просто фокусник который замутил видео-презентацию на пол-часа рассказывая о несуществующих генераторах и автоматизированых тестах? Если мне удастся решить — выложу на гитхаб, если нет — осрамлюсь перед всем доу ахахаха

я честно пытался понять что у вас не получилось, но похоже вы или не пробовали, либо не помните и вам лень вспоминать.

первичное проектирование, имплементация бекенда и фронтенда, обновление интерфейса (расширение, версионирование), обновление фронта и бека, обратная совместимость, тестирование, документирование (внутреннее и публичное для сторонних разработчиков), по сути поддержка всего этого.
Ваше предложение по написанию примера, которое вас должно по-идее удоволетворить, это по сути небольшая статья. Я конечно же могу её написать, но как-то на данный момент не планировал. Если есть конкретный затык в чем-то при реализации того что вы озвучили — напишите первую реальную проблему с которой столкнулись, тогда предметно обсудим, иначе где-то в глубине души складывается впечатление что я просто кормлю тролля.
Если вам вдруг придётся управлять большой командой, то вы увидите что не весь код, который пишется, написан вами, ахаха. С юмором у меня плохо, не спорю ;) Или вы хотите копипасту с моего проекта на который подписывался nda?

А я вот вам на зло всё-таки дам код, правда не пришлось ничего писать, там у них есть примерчики сгенерированых клиентов, и как раз по теме статьи.
github.com/...ular/API/Client/PetApi.ts
Swashbuckle мы тоже как раз использовали на сервере. Клиенты для интеграционных тестов на C# как раз-таки генерировали по апи с интегрированным свашбакл.

Я не пытаюсь придать этому негатива/позитива. Мне интересен опыт использования, которого потенциально нет.
у вас нет? У меня есть, я знаю точно! )))
И внедрение swagger это далеко не просто «код». Это решение. Которое может привести к вендорлоку и чему еще другому..
к вендорлоку? так вроде же оно опенсорс и на сервере swashbuckle очень non-invasive, немного аттрибутов тут и там и регистрация при app start.
Ничего из этого не тестировал на уровне API. Поэтому интересно, что и зачем вы тестировали?
а, ну так вот и выяснилось, вы сваггер апи не тестировали и генераторы не использовали, я правильно понимаю то что вы написали?
Я использовал swagger в связке с AWS API Gateway + Lambda. И Swashbuckle для внутреннего API. Ничего из этого не тестировал на уровне API.
WAT?
на уровне апи вы не тестировали — ваши слова
использовал. от этого, в частности про бекенд, и задал вопрос.
сомневаюсь, вы говорили что генераторы генерируют что-то не очень юзабельное:
а вы ими пользовались? то, что они генерируют... эмм
я потом вам дал ссылку на что-то очень юзабельное и вы вроде против ничего не имели
но для авто тестирования не использовал. поэтому я и задал вопрос про различный опыт тестирования. хоть общий смысл понятен, мне интересно было узнать о возможных подводных камнях.
подводный камень в вашем случае это то что вы не тестировали тот апи который написали. Как можно вообще не тестировать то что вы пишете? ахаха
вы же понимаете, что это самый минимум, который только можно придумать со swagger? Фактически это только генерирование web service proxy.
сваггер придумали для самодокументирования апи. Документация со свашбакелом и свагером была красивая, нам понравилась. Прокси мы сгенерировали автоматически и нам понравилось. Чего вам ещё от него надо? Чтобы он вам волшебно решил проблему версионирования и польку-бабочку сплясал? Сваггер есть сваггер, чего вы еще от него хотели ...
ок. просто зачем тогда писать про коллег и незнание кода вместо того, чтобы написать, как вы это использовали или использовали бы..
вы вроде тимлид, поэтому наверное знаете что надо делегировать, иначе будете красноглазить. Если вы пишете весь код на проекте — я вам сочувствую. Код я этот не писал, но код-ревью делал и презентацию коллеги смотрел тоже.
я предлагаю закончить наше обсуждение, т.к. оно абсолютно неинформативное.
а мне нравится обсуждение. Информативность есть, вот вы теперь знаете что апи надо покрывать авто-тестами обязательно. Просто не воспринимайте всё в штыки и давайте не будем друг друга подкалывать или делать вид что обижаемся или не понимаем ;)
вы даже не знаете, чем я занимался.
потихонечку узнаём, вы же сразу не рассказали ;)
вот куда прикручивать в AWS API Gateway swashbuckle (и зачем)?
ну это вы расскажите зачем, до сих пор же не совсем ясно чем вы там занимались и что это за gateway и контролируете ли вы этот gateway или он амазоновский.
И если вы генерировали отдельно статическую документацию, то вопрос, как у вас это было настроено на билд сервере, ведь для этого нужно было как-то получить yml, который в свою очередь живет в swashbuckle...
статическую не генерировали, достаточно было динамической
не драматизируйте :)
больше не буду, обещаю!!! ахаха
вы использовали Swagger UI и предоставляли доступ к нему клиенту? или это ваш внутренний API?
Свашбакл давал урл по которому можно было получить автосгенерированную документацию. Мы разрабатывали B2B API, внешние клиенты были, но не много, штук 10-15
вот интересный пример стека: AWS API Gateway + AWS Lambda + Swagger (хорошую статью нужно поискать, но пример вот).
спасибо за пример, всё вроде понятно. А как получилось так, что вам не надо было авто-тестировать тот restfull api который получался в результате?

Мабуть ви знаєте про десятки таких інструментів, тому вам не складно буде навести хоча б пару-трійку прикладів. Чи складно?

Ого! Прикольно. Здається саме можливість робити подібний опис, як це роблять за допомогою WSDL, у TypeScript є однією з найяскравіших корисних особливостей.

вот это да! А чем из тех что по ссылке пользовались для генерации строготипизированых клиентов?

так что же, сами не пользовались? может друзья рассказывали ... или просто первое запостили что гугл дал? Поделитесь, интересно ведь!

Костя, вот пример как раз по теме статьи — сгенерированый апи клиент на TypeScript github.com/...ular/API/Client/PetApi.ts
Инструмент называется swagger, на сервере устанавливается плагин для C# (WebApi) называется swashbuckle, который прокачивает ваш API до стандартов swagger. Там у них свои дополнительные правила для рестфул сервисов, поэтому получается уже не просто архитектурный стиль а такой-себе протокол ... ну, типа ;)
Потом вы берёте генератор и создаёте strongly-typed клиента автоматически, по типу того который по ссылке выше ... ну и в результате все счастливы (кроме Димы Решетникова, который видимо перфекционист и хочет чтобы я написал ему статью забесплатно).

Хех скриптер познакомился с нормальной типизацией, и стооолько эмоций))

Про це повинні знати усі «скриптери»! =)

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