Синтаксические конструкции и операторы¶
Кроме типизации, TypeScript пытается сделать жизнь разработчиков более комфортной за счет добавления синтаксического сахара в виде операторов, не существующих в JavaScript мире. Помимо этого, текущая глава поведает о неоднозначных моментах, связанных с уже хорошо известными по JavaScript операторами.
Операторы присваивания короткого замыкания (&&=, ||=, &&=)¶
В большинстве языков, в том числе и JavaScript, существует такое понятие как составные операторы присваивания (compound assignment operators), позволяющие совмещать операцию присваивания при помощи оператора =
с какой-либо другой допустимой операцией (+-*/!
и т.д.) и тем самым значительно сокращать выражения.
1 2 3 4 5 6 |
|
Множество существующих операторов совместимы с оператором =
за исключением трех часто применяемых операторов, таких как логическое И (&&
), логическое ИЛИ (||
) и оператор нулевого слияния (??
).
1 2 3 |
|
Поскольку дополнительные синтаксические возможности лишь упрощают процесс разработки программ, благодаря комьюнити в TypeScript появился механизм, обозначаемый как операторы присваивания короткого замыкания. Данный механизм позволяет совмещать упомянутые ранее операторы &&
, ||
и ??
непосредственно с оператором присваивания.
1 2 3 4 5 6 |
|
Операнды для delete должны быть необязательными¶
Представьте случай, при котором в JavaScript коде вам необходимо удалить у объекта одно из трех определенных в нем полей.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Задача предельно простая только с точки зрения динамической типизации JavaScript. С точки зрения статической типизации TypeScript, удаление члена объекта нарушает контракт, представляемый декларацией типа. Простыми словами, TypeScript не может гарантировать типобезопасность, пока не может гарантировать существование членов объекта, описанных в его типе.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Поэтому TypeScript позволяет удалять члены объекта при помощи оператора delete
только в том случае, если они имеют тип any
, unknown
, never
или объявлены как необязательные.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Объявление переменных 'необязательными' при деструктуризации массивоподобных объектов¶
При активном рекомендуемым флаге --noUnusedLocals
компилятор выбрасывает ошибки, если переменные, объявленные при деструктуризации массивоподобных объектов, не задействованы в коде.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Несмотря на то, что существует способ получать только необходимые значения, это не решит проблему семантики кода, поскольку идентификатор переменной является частью мозаики, иллюстрирующей работу логики. И хотя в TypeScript эту проблему можно решить и другими способами, они ничем не смогут помочь скомпилированному в JavaScript коду.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Для таких случаев в TypeScript существует возможность при деструктуризации массивоподобных объектов объявлять переменные как - необязательные. Чтобы переменная расценивалась компилятором как необязательная, её идентификатор должен начинаться с нижнего подчёркивания _identifier
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Модификатор abstract для описания типа конструктора¶
Абстрактные классы предназначены исключительно для расширения (невозможно создать его экземпляр с помощью оператора new
), а его абстрактные члены должны обязательно должны быть переопределены потомками.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Но правила, с помощью которых компилятор работает с абстрактными классами, делают типы абстрактных и конкретных конструкторов несовместимыми. Другими словами, абстрактный класс нельзя передать по ссылке, ограниченной более общим типом.
1 2 3 4 5 6 7 8 9 10 11 |
|
Кроме этого, невозможно получить тип экземпляра абстрактного класса с помощью вспомогательного типа InstanceType<T>
.
1 2 3 4 5 |
|
Это, в свою очередь, не позволяет реализовать механизм динамического наследования.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Для решения этой проблемы в TypeScript существует модификатор abstract
, предназначенный для указания в описании типа конструктора.
1 2 3 4 5 6 7 8 |
|
Несмотря на то, что тип класса имеет абстрактный модификатор, он также остается совместимым с типами конкретных классов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Также с помощью данного оператора можно реализовать собственный вспомогательный тип, позволяющий получить тип экземпляра.
1 2 3 |
|