Эта статья покажет вам, как быстро начать работать с TypeScript, и мы обсудим плюсы и минусы использования TS. TypeScript — это расширенный набор JavaScript и стандарта TC39. С помощью TS мы можем определять как простые, так и сложные статические типы для переменных в нашем коде.
TypeScript — это просто JavaScript с необязательным добавлением типов для ваших переменных. Вы можете писать в современном синтаксисе JavaScript (ES2015+) и использовать TypeScript, после чего с помощью компилятора преобразовывать TypeScript(.ts) в JavaScript(.js), и также при необходимости скомпилировать JavaScript с поддержкой предыдущих версий, таких как ES5.
Обратите внимание, что если вы используете require() или import/export, вам все равно нужно будет использовать сборщик для браузера, такой как Webpack, Rollup или SystemJS.
Устанавливаем TypeScript
Сначала установите TypeScript, используя npm:
npm install -g typescript
или с помощью yarn:
yarn global add typescript
После глобальной установки вам будет доступна команда в терминале tsc.
Урок 1. Установка программы T FLEX CAD
Компилируем .ts файлы
Используя терминал, создайте новый каталог с названием ts-simple с помощью следующей команды:
mkdir ts-simple
Перейдите в этот каталог и создайте файл index.ts. Внутри этого файла мы создадим функцию с именем sayHello и принимаемым аргументом name с типом string.
Теперь используем tsc для компиляции нашего index.ts:
tsc index.ts
Эта команда создаст новый файл index.js, предварительно удалив типизацию из параметра, а также преобразовав файл в код ES5. Полученный файл можно запустить в браузере или использовать в Node. Ваш файл будет выглядеть следующим образом:
Чтобы проверить это, запустите созданный файл, используя следующую команду:
node index.js // «Hello, gitconnected!»
Ошибки компиляции TypeScript
Одним из преимуществ TypeScript является то, что он может автоматически обнаруживать ошибки в вашем коде, если типы не совпадают. Например, представьте, что в приведенном выше примере, для параметра name мы вызываем функцию .trim(). Если мы передадим переменную любого другого типа, это может привести к тому, что наш код вызовет ошибку при воспроизведении в браузере. Давайте посмотрим на наш обновленный пример, неправильно передав массив в функцию:
Это приведет к следующей ошибке TypeScript при запуске команды tsc index.ts:
Если бы у нас не было TypeScript, защищающего нас и позволяющего исправить ошибку до того, как мы отправили код в продакшен, наши пользователи могли бы столкнуться со следующей ошибкой при посещении нашего веб-сайта.
T-Scan III: работа с программой T-Scan 8
Дополнительные расширения файлов TypeScript
В дополнение к файлам с расширением .ts вы также можете использовать расшируение .d.ts для добавления типов в уже существующие библиотеки JavasScript или файлы .tsx для написания синтаксиса JSX в TypeScript для приложений с React.
Преимущества TypeScript
- Вылавливает ошибки на этапе компиляции, а не во время исполнения. Типы позволяют нам распознавать проблемы, прежде чем они пойдут в продакшен.
- Автодополнение и подсветка синтаксиса. TypeScript поддерживается большинством основных IDE и текстовых редакторов, включая VS Code и Atom. Они предлагают мощные интеграции TypeScript, которые делают автоподстановку кода, указывают аргументы функции, не обращая внимания на источник, и обеспечивают встроенное распознавание ошибок.
- Улучшена читаемость кода. Структура, предоставляемая TS, значительно упрощает анализ нового кода, когда у вас строго типизированные переменные, функции и объекты. Это устраняет большую часть догадок о том, какую форму примут данные.
- Преобразование в ES2015+. Компилятор TypeScript обрабатывает весь современный JavaScript и может скомпилировать в предыдущих версиях JS для совместимости.
- Дополнительная статическая типизация. TypeScript не требует статической типизации всего, поэтому вы можете постепенно преобразовывать проект.
- Отличная экосистема. TypeScript существует с 2012 года, и на сегодня у него развитая и сильная экосистему. Многие пакеты с открытым исходным кодом предоставляют типы TypeScript в базовой сборке, что делает интеграцию еще проще.
- Увеличивает карьерные возможности. TypeScript стремительно растет, и его интегрировали многие крупные технологические компании, включая Google и Microsoft. Понимая TypeScript, вы повышаете свою конкурентоспособность при поиске работы.
- Бонус: нет необходимости в PropTypes при использовании TypeScript с React. Если вы используете TypeScript, вам больше не нужно управлять PropTypes в React, что позволяет вам быстрее отлавливать ошибки и более тесно связывать props с типами, используемыми в вашем коде.
Недостатки TypeScript
- Более высокая стоимость написания нового кода. Требуя больше кода, это может замедлить скорость разработки новых функций, что может быть не идеальным компромиссом для компании / стартапа.
- Еще одна библиотека для изучения. Если вы хотите использовать функции выходящие в новых версиях TS, потребуется рефакторить код по мере выхода новых версий.
- Кривая обучения для инженеров JavaScript. TypeScript потребует больше времени для погружения в проект новых людей, которые ранее работали только в JS.
- Сложные типы могут быть сложными для понимания. Если вы интегрируете TypeScript в существующую кодовую базу, у вас могут возникнуть проблемы с интеграцией в существующий функционал и обработкой сложных структур данных, которые «просто работали», когда это был только JS.
- Более подробный код. Хотя структура в конечном итоге полезна, компромисс в том, что вы будете использовать гораздо больше символов для написания того же объема кода по сравнению с JavaScript.
- Вам все еще нужен сборщик (например, Webpack, SystemJS и т. д.) Для нового синтаксиса, такого как импорт/экспорт модулей ES2015.
Источник: dev-gang.ru
Управляющие символы n t и прочие
Время от времени в коде вы можете встретить символы типа n , r , t и прочие.
Например, посмотрите что будет, если исполнить следующий код:
print(‘разtдваtтриnunotdosttres’)
# раз два три
# uno dos tres
Можно заметить, что вместо t у нас появился отступ, а вместо n переход на новую строку.
Символы вроде t и n — это управляющие символы, они управляют выводом, например модифицируют его.
Вот некоторые управляющие символы и их смысл:
n | (newline) перевод каретки на следующую строку |
r | (return) перевод каретки на в начало текущей строки |
t | (tab) табуляция (отступ, красная строка) |
b | (backspace) перевод каретки на один символ назад |
На заметку
В качестве разделителя строк в разных системах могут использоваться разные последовательности. Например, в Windows строки разделяются при помощи rn , а в Unix при помощи n .
Источник: pythonz.net
Как работать с типизацией в Python
Первые упоминания о подсказках типов в языке программирования Python появились в базе Python Enhancement Proposals (PEP-483). Такие подсказки нужны для улучшения статического анализа кода и автодополнения редакторами, что помогает снизить риски появления багов в коде.
В этой статье мы рассмотрим основы типизации кода Python и ее роль в динамически-типизированном языке, эта информация будет наиболее полезна для начинающих Python-разработчиков.
Типизация в Python
Для обозначения базовых типов переменных используются сами типы:
Пример использования базовых типов в python-функции:
def func(a: int, b: float) -> str: a: str = f», » return a
Помимо этого, можно параметризировать более сложные типы, например, List . Такие типы могут принимать значения параметров, которые помогают более точно описать тип функции. Так, например, List[int] указывает на то, что список состоит только из целочисленных значений.
from typing import List def func(n: int) -> List[int]: return list(range(n))
Кроме List , существуют и другие типы из модуля typing, которые можно параметризировать. Такие типы называются Generic-типами. Такого рода типа определены для многих встроенных в Python структур данных:
- Set[x]
- FrozenSet[x]
- ByteString[x]
- Dict[x, y]
- DefaultDict[x, y]
- OrderedDict[x, y]
- ChainMap[x,y]
- Counter[x, int]
- Deque[x]
- и т.д.
Как можно заметить, некоторые типы имеют несколько параметров, которые можно описать. Например, Dict[x, y] означает, что это будет словарь, где ключи будут иметь тип x , а значения – тип y .
Также есть более абстрактные типы, например:
- Mapping[x, y] – объект имеет реализации метода __getitem__ ;
- Iterable[x] – объект имеет реализацию метода __iter__ .
При этом функции тоже имеют свои типы. Например, для описания функции можно использовать тип Callable , где указываются типы входных параметров и возвращаемых значений. Пример использования:
from typing import Callable def func(f: Callable[[int, int], bool]) -> bool: return f(1,2) func(lambda x, y: x == y) >>> False
- говорит о том, что у объекта реализован метод __call__ ;
- описывает типы параметров к этому методу.
На первом месте стоит массив типов входных параметров, на втором — тип возвращаемого значения.
Про остальные абстрактные типы контейнеров можно прочитать в документации Python.
Также есть более конкретные типы, например Literal[x] , где x указывает не тип, а конкретное значение. Например Literal[3] означает цифру 3. Используют такой тип крайне редко.
Также Python позволяет определять свои Generic-типы.
from typing import TypeVar, Generic T = TypeVar(‘T’) class Stack(Generic[T]): def __init__(self) -> None: # Create an empty list with items of type T self.items: List[T] = [] def push(self, item: T) -> None: self.items.append(item) def pop(self) -> T: return self.items.pop() def empty(self) -> bool: return not self.items
В данном примере TypeVar означает переменную любого типа, которую можно подставить при указании. Например:
def func(stack: Stack[int]) -> None: stack.push(11) stack.push(-2) s = Stack[int]() func(s) s.empty() >>> False s.items >>> [11, -2]
Для определения собственных типов наследование возможно не только от Generic , но и от других абстрактных типов, например, таких, как Mapping , Iterable .
from typing import Generic, TypeVar, Mapping, Iterator, Dict KeyType = TypeVar(‘KeyType’) ValueType = TypeVar(‘ValueType’) class MyMap(Mapping[KeyType, ValueType]): # This is a generic subclass of Mapping def __getitem__(self, k: KeyType) -> ValueType: . # Implementations omitted def __iter__(self) -> Iterator[KeyType]: . def __len__(self) -> int: .
На месте KeyType или ValueType могут быть конкретные типы.
Также есть специальные конструкции, которые позволяют комбинировать типы. Например, Union[x, y, . ] — один из типов. Если переменной может быть как int , так и float , то как тип следует указать Union[int, float] . Если переменной может быть как int , так и None , то в качестве типа можно указать Union[int,None] или, что предпочтительно, Optional[int] .
Зачем это нужно
Цель — указать разработчику на ожидаемый тип данных при получении или возврате данных из функции или метода. В свою очередь, это позволяет сократить количество багов, ускорить написание кода и улучшить его качество.
Основные принципы программирования: статическая и динамическая типизация
Допустим, у вас есть класс юзера и функция, которая преобразует json в User .
Конечно, можно написать и проще:
def get_user_from_json(json_dict: Dict[str, Optional[Union[int, str]]]) -> User: return User(age=json_dict[«age»], name=json_dict[«name»], surname=json_dict[«surname»])
Однако, в обоих случаях может возникнуть ошибка, если ключ age будет присутствовать и при этом иметь строковый тип. Валидация типов добавляет не очень много строк кода, но при большом количестве моделей может занимать немало места в проекте.
Использование Pydantic помогает корректно валидировать данные, при этом тип автоматически поменяется на требуемый.
from pydantic import BaseModel class User(BaseModel): name: str surname: str age: int def get_user_from_json(json_dict: Dict[str, Optional[Union[int, str]]]) -> User: return User(**json_dict) get_user_from_json(< «name»: «ssa», «surname»: «ddd», «age»: 10 >) >>> User(name=’ssa’, surname=’ddd’, age=10) get_user_from_json(< «name»: «ssa», «surname»: «ddd», «age»: «10» >) >>> User(name=’ssa’, surname=’ddd’, age=10) get_user_from_json(< «name»: «ssa», «surname»: «ddd», «age»: «d» >) ————————————— ValidationError: 1 validation error for User age value is not a valid integer (type=type_error.integer)
Как можно заметить, более строгая типизация кода помогает сделать его проще и безопаснее. Однако, использование некоторых возможностей Pydantic может нежелательно повлиять на код. Так, мутация данных при валидации способна привести к тому, что тип значения модели будет непонятен. Например:
В данном примере созданный User после валидации будет иметь отличный от того, который был указан в модели. Это ведет к возможным крупным багам, которые лучше всегда избегать.
Также сейчас набирает большую популярность фреймворк FastAPI, который, благодаря Pydantic, позволяет быстро писать веб-приложения с автоматической валидацией данных.
В данном примере эндпоинт /item автоматически валидирует входящий json и передает его в функцию как требуемую модель.
Также для уменьшения количества багов используют mypy, который позволяет проводить статический анализ кода на соответствие типов. За счет этого зачастую можно избежать очевидных багов или несоответствий типов в функциях.
И как бонус для тех, кто ленится вручную поддерживать типизацию. MonkeyType дает возможность автоматически проставить типы во всех функциях, хотя после запуска этой программы обычно требуется пройтись по коду и поправить некоторые значения, которые оказались распознаны не так, как предполагалось.
Нововведения Python 3.9.0
Начиная с недавно вышедшей версии Python 3.9, у разработчиков больше нет необходимости импортировать абстрактные коллекции для описания типов. Теперь вместо typing.Dict[x, y] можно использовать dict[x,y] , то же самое происходит с Deque , List , Counter и т.д. Полное описание этого нововведения можно прочитать тут: PEP-585.
Также добавили аннотации типов, которые в дальнейшем могут быть использованы инструментами статического анализа. variable: Annotated[T, x] где T — тип переменной variable , а x — некоторые метаданные для переменной. По оценкам некоторых авторов, эти метаданные могут быть использованы также и во время выполнения (подробности смотрите в PEP-593).
Заключение
В этой статье мы рассмотрели некоторые типы в языке Python. В заключение отметим, что типизированный код в Python становится намного более читаемым и очевидным, что помогает проводить ревью в команде и не допускать глупых ошибок. Хорошее описание типов также позволяет разработчикам быстрее влиться в проект, понять, что происходит, и погрузиться в задачи. Также при использовании определенных библиотек удается в несколько раз сократить количество строк кода, которые ранее требовались только для валидации типов и значений.
Источник: tproger.ru