Как сделать типизацию

Обновлено: 03.07.2024

Инструменты для статической типизации, такие как Flow или TypeScript, позволяют отлавливать большую часть ошибок ещё до исполнения кода. Кроме того, они существенно улучшают процессы разработки, добавляя автодополнение и другие возможности. Для приложений с большой кодовой базой мы рекомендуем использовать Flow или TypeScript вместо PropTypes .

Flow — это библиотека для статической типизации JavaScript, разработанная в Facebook и часто применяемая в связке с React. Flow расширяет возможности JavaScript, добавляя аннотации типов для переменных, функций и React-компонентов. Ознакомиться с основами Flow можно на странице официальной документации.

Чтобы начать пользоваться возможностями Flow необходимо:

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

Рассмотрим подробнее каждый из этих шагов.

Добавление Flow в проект¶

Убедитесь, что вы находитесь в директории проекта, после чего запустите одну из следующих команд:

Если вы используете Yarn:

Если вы используете npm:

Эти команды добавят последнюю версию Flow в ваш проект.

Далее нужно добавить flow в секцию "scripts" файла package.json :

Теперь можно запустить скрипт, прописав в терминале:

Эти команды создадут файл с исходной конфигурацией Flow, который обязательно нужно закоммитить.

Удаление аннотаций Flow из скомпилированного кода¶

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

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

Create React App¶

Если для изначальной конфигурации проекта вы выбрали Create React App, вам ничего не нужно делать! Проект уже настроен должным образом и аннотации Flow должны удаляться при сборке проекта.

Babel¶

Примечание:

Дальнейшие инструкции рассчитаны на тех, кто не использует Create React App, т.к. там уже есть все необходимые настройки для работы с Flow.

Если для своего проекта вы самостоятельно настраивали Babel, нужно установить специальный пресет для работы с Flow:

Затем добавьте установленный пресет flow в свою конфигурацию Babel. Например так, если вы используете конфигурационный файл .babelrc :

Этот пресет позволит использовать Flow в вашем коде.

Примечание:

Для работы с Flow не требуется отдельно устанавливать пресет react — Flow уже понимает JSX синтаксис. Тем не менее, часто используют оба пресета одновременно.

Другие инструменты сборки¶

Для удаления аннотаций Flow существует отдельная библиотека: flow-remove-types. Она может пригодиться, если вы пользуетесь другими инструментами для сборки проекта.

Запуск Flow¶

Если всё было сделано правильно, можно попробовать запустить процесс Flow:

Добавление аннотаций типов¶

По умолчанию Flow проверяет только файлы, содержащие специальную аннотацию (обычно её указывают в самом начале файла):

Попробуйте добавить эту аннотацию в некоторые файлы вашего проекта, а затем запустить скрипт yarn flow или npm run flow и посмотреть, найдёт ли Flow какие-нибудь ошибки.

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

Всё должно работать! Советуем изучить Flow подробнее, ознакомившись со следующими ресурсами:

TypeScript¶

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

Чтобы использовать TypeScript, нужно:

  • добавить TypeScript в проект как зависимость.
  • настроить компилятор.
  • использовать правильные расширения файлов.
  • установить файлы объявлений для используемых библиотек;

Остановимся подробнее на каждом из этих моментов.

Использование TypeScript вместе с Create React App¶

Create React App поддерживает TypeScript по умолчанию.

Чтобы создать новый проект с поддержкой TypeScript, используйте следующую команду:

Можно добавить поддержку TypeScript в уже существующий проект, как показано здесь.

Примечание:

Дальше описывается ручная настройка TypeScript. Если вы используете Create React App, можете пропустить этот раздел.

Добавление TypeScript в проект¶

Всё начинается с одной единственной команды в терминале:

Ура! Вы установили последнюю версию TypeScript. Теперь в вашем распоряжении новая команда — tsc . Но прежде, чем праздновать, давайте добавим соответствующий скрипт в файл package.json :

Настройка компилятора TypeScript¶

Сам по себе компилятор бесполезен, пока мы не скажем, что именно ему нужно делать. Для этого есть специальный конфигурационный файл tsconfig.json . Создадим этот файл:

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

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

Эту проблему можно решить в два шага:

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

Отлично! Теперь, если мы запустим скрипт сборки проекта, компилятор сохранит готовый JavaScript в директорию build . В TypeScript React Starter уже есть готовый tsconfig.json с неплохим набором параметров для дальнейшей тонкой настройки под себя.

Как правило, скомпилированный JavaScript-бандл не следует хранить в системе контроля версий, так что не забудьте добавить папку build в файл .gitignore .

Расширения файлов¶

В React мы почти всегда используем .js в качестве расширений файлов компонентов. В TypeScript лучше разделять файлы на два типа:

.tsx для файлов, содержащих JSX разметку, и .ts для всего остального.

Запуск TypeScript¶

Если всё было сделано правильно, можно попробовать скомпилировать TypeScript:

Если эта команда не вывела ничего в терминале, то процесс компиляции прошёл успешно.

Определения типов¶

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

Существует два основных способа получения файлов объявлений:

Bundled — Библиотека устанавливается вместе с собственным файлом объявлений. Это прекрасный вариант для нас, так как всё, что нам нужно — установить нужный пакет. Чтобы проверить, есть ли у библиотеки файл объявлений, поищите index.d.ts в её исходных файлах. В некоторых библиотеках наличие и расположение этого файла указываются в package.json в секциях typings или types .

DefinitelyTyped — это внушительный репозиторий файлов объявлений. Например, React устанавливается без собственного файла объявления — вместо этого мы устанавливаем его отдельно:

Локальные объявления Иногда пакет, который вы хотите использовать, не имеет ни собственного файла объявлений, ни соответствующего файла в репозитории DefinitelyTyped. В этом случае, мы можем объявить собственный локальный файл объявлений. Для этого надо создать файл declarations.d.ts в корне директории, где лежат исходники вашего проекта. Файл объявлений может выглядеть примерно так:

Вот и всё, вы готовы писать код на TypeScript! Чтобы познакомиться с ним поближе, рекомендуем посетить эти ресурсы:

Reason¶

Reason — это не новый язык, а новый синтаксис и набор инструментов для проверенного временем языка OCaml. Reason предоставляет синтаксис, ориентированный на JavaScript программистов, и использует уже известный всем способ распространения через NPM/Yarn.

Reason был разработан в Facebook и используется в некоторых продуктах этой компании — например, в Messenger. Reason всё ещё считается довольно экспериментальным инструментом, но уже имеет библиотеку привязок для React, поддерживаемую Facebook, а также отзывчивое сообщество

Kotlin¶

Kotlin – это язык со статической типизацией, разработанный в JetBrains. Он нацелен на платформы работающие на основе JVM, Android, LLVM и JavaScript.

JetBrains разрабатывает и поддерживает несколько библиотек специально для сообщества React: React bindings совместно с Create React Kotlin App. Последняя позволит вам начать использовать Kotlin вместе с React в одном проекте без необходимости ручной конфигурации.

Другие языки¶

С каждой версией язык php обрастает новыми возможностями, делая жизнь разработчиков проще. В этой статье мы обсудим возможности типизации в современных версиях PHP и преимущества использования типов.

Типизация в PHP

В языке PHP динамическая типизация. Это значит, что при инициализации переменной ей нельзя назначить тип. Тип переменной выставиться динамически в зависимости от значения (или результат выполнения выражения), которое ей присваивается. Он может меняться в процессе выполнения скрипта. Продемонстрирую на примере:

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

Типизация аргументов в функциях и методах

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

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

TypeError: Argument 1 passed to myTestOperation() must be of the type int, string given

Если удалить строчку declare(strict_types=1) , PHP попытается преобразовать переданную строку в число. Если преобразовать невозможно, PHP выбросит исключение TypeError.

Типы аргументов и тип возвращаемого значения могу быть следующими:

  • int - целочисленный тип;
  • float - числа с плавающей точкой (десятичная дробь);
  • string - строка;
  • array - массив;
  • callable - callback-функция;
  • имя класса - в качестве аргумента должен передаваться экземпляр класса;
  • интерфейс - в качестве аргумента должен передаваться класс, имплементирующий (реализующий) данный интерфейс.

Null и void в сигнатуре функции

В случае, если функция или метод класса не возвращают значение, после двоеточия пишется ключевое слово void.

В случае, если какие-то из аргументов функции мы захотим сделать необязательными, на нужно добавить знак ? перед именем типа. Это правило работает и для возвращаемого значения. Например, для аргумента ?int $myVar можно передать значение либо null, либо целое число. Чтобы явно не передавать null в качестве значения необязательного аргумента, обычно в сигнатуре присваивают значение по умолчанию, как показано в следующем примере:

Языки программирования по типизации делятся на два больших лагеря — типизированные и не типизированные.

Типизированные языки

К типизированным языкам относятся

  • C/C++
  • Python, PHP, Ruby
  • Lua, JavaScript, Action Script

Не типизированные языки

  • Ассемблер
  • Forth
  • Brainfuck

Да-да, именно так. JavaScript, как и многие другие интерпретируемые языки — типизированный. Поэтому ни в коем случае не говорите, что он не типизированный. Особенно на собеседованиях!

В свою очередь, типизированные языки разделяются еще на несколько пересекающихся категорий:

  • Со статической или динамической типизацией.
  • Со строгой или нестрогой типизацией.
  • С явной или неявной типизацией.

Языки со статической типизацией

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

TypeScript — язык со статической типизацией.

Языки с динамической типизацией

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

Представители: JavaScript, PHP, Python, Ruby…

Строгая типизация (сильная)

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

Представители: Java, Python, Haskell, Lisp…

Кстати TypeScript добавляет строгую типизацию и не позволяет смешивать типы:

Нестрогая типизация (слабая)

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

Представители: JavaScript (йаху!), Lua, Visual Basic, PHP…

Явная типизация

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

Кстати TypeScript — язык с явной и неявной строгой типизацией одновременно. Неявная типизация досталась от JS (так как TS — это JS). А вот фича и особенность TS — это его природа явно типизированного языка.

Неявная типизация

В языках с неявной типизацией задачу по указанию типов перекладывают на компилятор/интерпретатор.

Представители: JavaScript (еее!), PHP, Lua, Python (хотя с версии 3 есть аннотации типов, которые как бы добавляют явную типизацию)…

В таких языках, как правило, у объектов существуют специальные методы, вызываемые при приведении к типу. К примеру, в PHP есть метод _toString(), а в JavaScript одноименный метод, но без подчеркивания — toString(). Эти методы вызываются при приведении объекта к строковому типу. Иногда такие методы называют магическими (любые неявные процессы — это всегда магия).

Важно заметить, что все эти категории пересекаются. Исходя из этих категорий, получаем, что JavaScript имеет динамическую неявную типизацию. При этом TypeScript имеет статическую строгую явную типизацию с возможностями неявно типизированного языка, но компилируется (транслируется/транспилируется) в рантайм код с неявной динамической типизацией.

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

Статическая печать

Языки программирования со статической типизацией — это те, в которых переменные не должны быть определены до их использования. Это подразумевает, что статическая типизация имеет отношение к явному объявлению (или инициализации) переменных перед их использованием. Java является примером статического типизированного языка; C и C ++ также являются статическими типизированными языками. Обратите внимание, что в C (и C ++ также) переменные могут быть преобразованы в другие типы, но они не преобразуются; Вы просто читаете их, предполагая, что они другого типа.

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

Приведенный выше фрагмент кода является примером того, как обычно выглядит объявление переменной в статических типизированных языках. Обратите внимание, что в приведенном выше коде static имеет ничего общего со статической типизацией; он использовался вместе с int только для инициализации num и суммирования до нуля.

Динамический набор текста

Динамически типизированные языки программирования — это те языки, в которых переменные должны быть обязательно определены перед их использованием. Это подразумевает, что динамически типизированные языки не требуют явного объявления переменных перед их использованием. Python является примером динамического типизированного языка программирования, как и PHP. Рассмотрим следующий пример:

В приведенном выше фрагменте кода мы непосредственно присвоили переменной num значение 10 перед его инициализацией. Это характерно для динамически типизированных языков программирования.

Другая аналогия

Многие люди определяют статическую типизацию и динамическую типизацию относительно точки, в которой проверяются типы переменных. Используя эту аналогию, статические типизированные языки — это те, в которых проверка типов выполняется во время компиляции, тогда как динамические типизированные языки — это те, в которых проверка типов выполняется во время выполнения.

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

Статическая и динамическая типизация в сравнении со строгой и слабой типизацией

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

Сильный набор текста

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

Читайте также: