Рубрики
Без рубрики

Как я переключился из TypeyctScript, чтобы повторно

Проблеск в более цивилизованный (еще сложный) инструмент в экосистеме JavaScript Статья оригинал … Помечено в TypeScript, JavaScript, React, Rescript.

Проблеск в более цивилизованный (еще сложный) инструмент в экосистеме JavaScript

Статья первоначально опубликована в Середина

Это не евангелизация повторного или однозначного сравнения с помощью Teadercript. Я люблю Tearscript. Я решил переписать небольшой проект Side Tymdercript + React + Jest в Rescript.

Ресист не новая. Так же стареть как сам JavaScript. Rescript – это ребрендинг RUBINGML ( Facebook ) и BescleScript ( Bloomberg ), какая оберная Ocaml на обоих концах. Первый – это интерфейс синтаксиса OCAML, в то время как последний не должен составить AST в JavaScript. Разум был создан Иордан Уалке, создателем реагирования. Разумный Еще существует как параллельный проект для охрана, с немного другим синтаксисом и миссией.

Синструкрин синтаксис, составляющий в окамле абстрактный синтаксис, а изысканчик, компилируемый в читаемый, оптимизированный JavaScript

Rescript – это не просто ребрендинг: это разум, который освободил себя с ярком экосистемы Ocaml. Делая это, он утратил компиляцию на нативный кодовый кодекс и взаимодействовать с библиотекой Ocaml, но приобрел синтаксис Freer, который дополнительно напоминает JavaScript, чтобы охватить своих разработчиков, стремиться к лучшим инструментам.

Моя первая попытка была просто установить Rescript на моем проекте, запускайте наблюдателя, переименуйте простой файл в .res.res. и руководствоваться ошибками. Я немедленно узнал, что рефакторинг в реструкту не является «шириной – сначала», но «в первую очередь». Просто переименование расширения файла не будет работать, так как компилятор полностью останавливается на ошибках типа.

В Teadercript можно постепенно назначать типы и интерфейсы для динамических типов, в то время как метка некоторые как Неизвестно или любой Отказ Глубина – сначала означает, что вы начинаете с одной маленькой функции или одного небольшого реагирования, и правильно запишите его. Если все типы правы – и с математической точностью – ваш код будет скомпилировать в JavaScript.

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

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

Но как насчет TypeyctScript? Межаную работу с JavaScript Code Trivial, но типы импорта и экспорта из TypectScript (или поток) могут быть более сложными, и он создает два источника истины: один для типовсердровков и другого для Teadercript.

Gentype, описанный ниже, автоматически генерирует набранный TSX Файл из вашего повторного кода, который вы можете импортировать в другие модули. Это помогло для экспорта типовсердровных типов, но невозможно импортировать Tearscript. Автоматизация преобразований типа ослабил проблему двух источников истины.

Кроме того, сгенерированный код TS использует Commonjs требуется Синтаксис, который нарушается при использовании собственного модуля Ecmascript. Я также должен был настроить мой TSC не транспортировать автогенерируемые TSX в четвертый (!) Исходный файл:

  • .res.res. Исходный код Rescript.
  • .bs.js скомпилирован JavaScript, который вы можете игнорировать в вашем исходном управлении
  • .gen.tsx Автоматически генерируется GECTYPE, который импортирует скомпилированный код JavaScript и повторно экспортируйте его с помощью правильных типов. Также добавьте к вашему .gitignore. .
  • .gen.jsx Случайно транспортирован по TypeScript, удалите его и переконфигурируйте свой tsconfig.json Отказ

Сначала я переписал свои алгоритмы, поскольку у них не было никаких сторонних импорта для взаимодействия, а синтаксис импорта был пугающим для меня сначала. Некоторые команды идут на Первая стратегия данных или UI-первая (Как сделал Facebook в 2017 году для Messenger.com, Переписать 50% от кодовой базы ).

Rescript является частью Статически набранный функциональный язык программирования Семья , что означает, что это не компиляция. Просто шучу, это означает, что он использует алгоритм типа Hindley-Miller, который выводит типы с 100% уверенностью и может доказать его математически, если ваши переменные неизменяются (и несколько других выборов дизайна языка). TypeScript с другой стороны пытается сделать это лучшее в поисках общего типа для всех ваших использования.

Это может взорвать ваш разум как пользователь Tymdercript, но следующая функция Rescript полностью набирается статически:

let add = (a, b) => a + b

Rescript знает с доплатой уверенностью, что А и преступность оба int. И что функция возвращает int Отказ Это потому, что + Оператор работает только на двух int и возвращает int Отказ Чтобы объединить две строки, которые вы использовали ++ И для двух поплавков используют +. . Чтобы объединить два разных типа, которые вам нужно преобразовать любой из них. Также никаких точек с запятой.

Если вы похожи на меня и хотите набрать свой код в качестве прототипа, вы можете сделать это так, как вы ожидаете:

let add = (a: int, b: int): int => a + b

Сгенерированный код JavaScript в обоих случаях одинаково (Rescript V8.4.2):

'use strict';
function add(a, b) {  
    return a + b | 0;  
}
exports.add = add;

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

Вы можете попробовать это для себя в официальном Детская площадка Отказ

Чтобы взаимодействовать с Teadercript с соответствующей информацией о типе, вы будете использовать стороннюю Гентип Отказ Добавьте его как devdependentency и аннотировать экспорт модуля, который вы хотите сгенерировать с @gentype (В предыдущих версиях вы должны окружить аннотации с квадратными скобками).

// MyModule.res
@genType  
let add = (a,b) => a + b

Это приведет к следующему типографию. Обратите внимание, как сгенерированный TeampStry импортирует сгенерированный JavaScript Mymodule.bs.js файл:

// MyModule.gen.tsx
const MyModuleBS = require('./MyModule.bs');
export const add: (_1:number, _2:number) => number = MyModuleBS.add;

Gentype генерирует один реэкспорт вашего сгенерированного .bs.js Файл с надлежащей печати Teadercript. Из этого примера вы заметите еще два веща:

  • Каждый файл – это модуль.
  • Все экспортируется.

Вот и Пример REPO GENCYPING на Teamscript с реагированием.

Для использования типов типов, см. «Импорт типов типографических типов» ниже.

Есть только один тип, который нуждается в декларации типа, которая является Запись тип. Такая декларация типа будет выглядеть так и производит код JavaScript:

type student = {  
  age: int,  
  name: string  
}

Типы должны начинаться с строкой! Если мы добавим это с помощью @gentype. Сгенерированный типограф будет выглядеть так:

// tslint:disable-next-line:interface-over-type-literal_  
export type student = {  
    readonly age: number;  
    readonly name: string  
};

Если вы видите в типе нижнего кожуха, нарушающие все свои конвенции, вы можете переименовать тип преобразования с @ gentype.as («студент») . Это добавит еще одну строку кода ниже предыдущего:

export type Student = student;

Также он включает в себя Цлинт Игнорировать линию, которую я надеюсь, что они скоро переключаются на Eslint Как бывший устарел.

Это типы записи, а не осмотреть Объекты (Не злоупотребляйте String Тип на них). Как только вы введите что-то вроде foo.age Rescript узнает, что Foo имеет тип ученик . В случае, если есть еще одна запись и возраст Поле, это вывод, что заявлено последнее. В этом случае вы можете явно аннотировать тип.

В случае, если вы не хотите, чтобы это много церемонии, вы можете использовать объект Введите и индексируйте его со строкой: Студент [«Возраст»] ; Тогда вам не нужно объявлять тип.

Кроме того, вы можете использовать Студент Как имя переменной, так Student.age Является действительным выражением, Tymdercript закричал бы на что-то подобное. Переменные (то есть привязки) и типы живут в отдельном пространстве имен, поэтому A Студент типа Студент Будьте написаны как Студент: Студент Отказ

Типы записей имеют « Номинальные набрав », похожие на Java или C #, в отличие от TypeyScript’s « структурное набрав. «Вот почему интерфейсы настолько важны в Teadercript, и используются гораздо больше, чем типы. Teadncript на самом деле не заботится о « То, что вы являетесь », оно заботится о « Как ты выглядишь ».

Например, если есть другой тип, скажем, Учитель с такими же полями Студент Вы не можете назначить Студент Где-то ожидая Учитель :

// defined first  
type student = {  
  age: int,  
  name: string  
}

// defined last  
type teacher = {  
    age: int,  
    name: string  
}

// t is a teacher  
let t = {  
    age: 35,  
    name: "Ronen"  
}

let s: student = t // Error!

Вы получите цветную ошибку:

We've found a bug for you!
//...This has type: teacher
Somewhere wanted: student  
FAILED: cannot make progress due to previous errors.  
>>>> Finish compiling(exit: 1)

В отличие от TypectScript’s TSC Компилятор, BSB не будет неожиданно продолжать свою транспинацию работать в рабочий JavaScript. Он остановится с ненулевым кодом выхода, и вы должны исправить проблему, чтобы сделать любой прогресс.

Одна из функций, которые я больше всего люблю в современном типеприкторе (или будущем JavaScript), являются дополнительными элементами. Они делают работу с ненугими типами простой и лаконичной:

const что-то:?. Бар? .baz ?? “По умолчанию”;

что-то будет содержание Баз Если он достиг этого далеко или будь "по умолчанию" Отказ

Нет null или undefined в реструктуре. Но мы можем работать с ненугими значениями, используя вариант Опция Отказ Но как мы можем получить элегантность вышеуказанного Tymdercript Code? Я пытался ответить на этот вопрос Но мы не можем, в настоящее время. Недостаточно сахара.

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

  • Пояс. Вариант. Карта будет выполнять функцию необязательного значения, если она существует или return Нет Отказ
  • Пояс. Option.getwithdefault вернет по умолчанию, если опционально это Нет Отказ
  • Пояс. Array.keepmap Обрежу все Нет значения из массива.

Но для этого дела лучший вариант с Схема сопоставления :

let baz = switch foo {  
   | Some({ bar: Some({ baz: baz })}) => baz  
   | None => None  
}

Там нет еще не сахарный синтаксис для дополнительных объектов; Дополнительные операторы также очень новые для Teadercript.

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

Трубы великолепны. Они компилируют этот код:

person  
  ->parseData  
  ->getAge  
  ->validateAge

В это:

validateAge(getAge(parseData(person)));

Предыдущие версии использовали оператор треугольника |> . Разница находится в том, где выпустить данные: в качестве первого параметра, поскольку стрелка делает, или в качестве последнего параметра, как делает устаревший треугольник. Подробнее об этом.

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

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

Каким был бы вызов метода JavaScript, такой как карта:

myArray.map(value => console.log(value));

Должен быть написан функционально в реструкту, как:

Belt.Array.map(myArray, value => Js.log(value))

Но можно переписать как:

myArray -> Belt.Array.map(value => Js.log(value))

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

Кстати, если вы не используете Фирский код Тогда вы пропускаете много эстетики трубы.

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

Следующий код:

const getName = async (id: number): Promise => {  
    const user = await fetchUser(id);  
    return user.name;  
}

Не сахарный в:

const getName = async (id: number): Promise =>   
    fetchUser(id).then(user => user.name);

Теперь рассмотрим тогда быть функцией в Js. Обещания модуль вместо метода, который принимает Fetchuser (ID) В качестве последнего параметра, и вы можете написать так:

let getName = (id) =>  
    Js.Promise.then_(  
        user => Js.Promise.resolve(user.name),  
        fetchUser(id))

Набран как Js. Обещание.t , а с синтаксисом трубы стрелка для чтения, приведенная выше функция может быть написана как:

let getName = (id): Js.Promise.t =>  
    fetchUser(id) |> Js.Promise.then_(  
        user => Js.Promise.resolve(user.name))

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

Вот Примеры Для обещаний, написанных в (почти идентичном) синтаксисе разусадности.

The Rescript Team Обещал (без каламбура) реализовать обещание API BELAGE со своими async и ждать Отказ

Если вы пишете только в Rescript, вам не нужно беспокоить импорт или экспорт, и это делается под капотом. Каждый файл – это модуль, и все в нем экспортируется. Если вы только хотите, чтобы конкретные вещи были экспортированы, вы делаете это с файлом интерфейса. Однако для импорта модулей JavaScript синтаксис может усложняться.

Импортировать Дирнама от путь Модуль, вы бы написали:

@ Bs.Module («Путь») Внешний дирнама : строка =>

Элементы импорта из файлов JavaScript

Затем используйте его соответственно:

let root = dirname("/User/github") // returns "User"

Для рассуждений это стало особенно утомительным, так как мне пришлось определить встроенные модули для каждого компонента реагирования, и повторить экспорт по умолчанию как функцию «Make», обращая внимание на названные параметры, такие как «дети». Здесь я импортировал контейнер от React-bootstrap и использовал его в разбуждении:

module Container = {  
    @bs.module("react-bootstrap/Container")  
    @react.component  
    external make: (~children: React.element) => React.element = "default"  
}
@react.component  
let make = () =>  ...

Для этого я могу получить привязки от Redex, и добавьте его как зависимость как для моего Package.json. и мой bsconfig.json. . Затем я могу импортировать его с Откройте реакции на реакции в верхней части моего файла. Это похоже на Определенно, Где вы можете найти высококачественные определения типа для TypeyctScript.

Для этого случаи, однако, я бежал в ошибку, поскольку в пакете мне нужно было не обновлено до последней версии. Я должен был вилить это и Обновите вручную Это до React-JSX Версия 3

Вы не можете импортировать тип из TypeyctScript и используйте его в оформлении, вы должны повторно объявить его. Тем не менее, вы можете связать тип, который вы создали в оригинальный Teamplect One для правильной взаимодействия. Вот пример с Node.js ‘ ФС Модуль:

@genType.import(("fs", "Dirent"))  
type dirent

Обратите внимание, что я прошел кортеж к импорт , а не список аргументов. Это свяжет мой тип ущерб к FS. Дирент и будет генерировать следующую машину:

import {Dirent as $$dirent} from 'fs';_// tslint:disable-next-line:interface-over-type-literal_  
export type dirent = $$dirent;

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

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

Разумность (сейчас Rescript) была создана Джорданом Уолке, создателем реагирования. Причина + реагируют толкает философию реагирования, используя языковой синтаксис и функции для рисунков программирования INVEJS.

Разумность обеспечивает гладкое взаимодействие JS и использует встроенные языковые функции для интеграции в структуру MODENGE UI, оставленные безднеменной реактивными ресурсами, такими как маршрутизация и управление данными. Использование их чувствует себя как « просто используя причину.

Документация для рассуждений по-прежнему использует старый синтаксис, поэтому вещи, такие как:

[@react.component]

Должен быть изменен в:

@react.component

Если вы хотите использовать старый синтаксис, просто измените расширение файла в .rea вместо .res.res. .

Разумность является более строгим, чем ReactJS, в основном при использовании типов (например, строки необходимо использовать с Rect.String () в JSX. Кроме этого, Rect.Usestate Возвращает правильное кортеж Вместо массива, как это было первоначально предназначено. Наконец, компоненты React предоставляются через сделать Функция и добавлена @ racte.component (Я добавил @gentype Также для генерации Typeycts):

Для примера я импортировал этот компонент в файл ract teampscript:

// index.tsx
import { make as Demo } from "./pages/Demo.gen";
// ...

Который, когда визуализируется, выглядит так:

В случае, если мы не хотим Gentype для генерации TeampStry, мы просто импортируем Demo.bs вместо.

Для того, чтобы написать тесты в Rescript, и, таким образом, проверьте ваш код напрямую, вы можете использовать BS-jest, который предоставляет привязки Rescript для шума. Если вы предпочитаете, вы также можете использовать чуть менее зрелый BS-Mocha Отказ Вы также можете проверить генерируемые файлы JavaScript или Tearmscript без дополнительной конфигурации.

Поскольку Rescript находится в javaScript Ecosystem, мало что имеет смысл создавать специализированные инструменты тестирования для повторного использования, а направление, по-видимому, в разработке привязки для инструментов тестирования JavaScript.

С BS-Jest вы должны назвать вы не можете назвать ваш файл foo.spec.res , только с действительным именем модуля, такого как foo_spec.res Отказ Jest будет работать в составленной папке по умолчанию внутри lib/js. . Кроме того, утверждения не выполняются немедленно, но вместо этого возвращаются функцией и запущены в конце Suite. Это функциональный способ к тестам. Следовательно, вы можете написать только одно утверждение за тест, что в любом случае является лучшей практикой.

Rescript Devs хорошо приоритет приоритетировать Плагин для VSCode, который работает очень хорошо. Благодаря запуску наблюдателя Rescript, вы увидите ошибки вашего типа, подчеркиваемые красным, с описательным пузырем на наклоне. Вы также получаете подсказки типа, форматирование и переход к определениям. Есть также официальная поддержка для Vim (как простой сервер языка Vim и CoC) и Возвышенный Отказ

Захват экрана от Rescript-VSCode Отказ

Несколько раз в моей кодированной карьере мне пришлось работать с небольшими общинами, и я всегда любил его. Я разработал умные контракты в Солидность Некоторые запросы базы данных на функциональном языке Q, и каналы Roku в BrightScript . Вы в конечном итоге работаете с Slack/Discord/Gitter Open и Code вместе с несколькими другими, которые проходят ваши подобные проблемы. Вы даже не поморите проверку Stackoverflow для ответов.

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

Не все общины похожи, конечно. Я лично нашел сообщество RUSIML/RESPRICT, чтобы приветствовать. Rescript имеет Официальный форум Где вы можете общаться асинхронно и с постоянной записью бумаги, вы можете искать. Основная команда состоит из Горсть разработчиков с публичными учетными записями Twitter, и есть официальный блог . Однако я нашел, что сообщество висит в Server Server Server в неофициальной респ-комнате.

Наконец, есть Подтвердить , «Подкаст о языке RUSIML и сообществу, который делает его хорошим», – Разумность сон Канал YouTube, а Redex , чтобы найти привязки для ваших библиотек.

Переключатель не прост; Рефактор существующего приложения еще сложнее, учитывая его смертельную остановку в первом выпуске. Это, безусловно, препятствует его принятию. Популярные транспорты, такие как Tymdscript, SCSS или CoffeeScript, получили его легкость. Просто скопируйте-вставьте свой код – или переименуйте свой файл – и вы закончите.

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

Мы уже на первом этапе принятия «функционального стиля» в экосистеме с карта , Фильтр , Уменьшить Функции в JavaScript. Rescript представляют следующую – гибридный этап – правильно функционального языка из семейства ML, который компилирует стандартную JavaScript в отрасли.

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

Оригинал: “https://dev.to/ronenl/how-i-switched-from-typescript-to-rescript-1g34”