Заголовочные файлы
Работа с заголовочными файлами
Рассмотрим, как мы можем использовать заголовочные файлы. Иногда в программах на javascript используются глобальные переменные, которые должны быть видны для всех функций приложения. Например, пусть на веб-странице (или во внешнем подключаемом файле javascript) в коде js определена переменная:
В данном случае для простоты переменная определена веб-странице, хотя она также могла быть определена во внешнем подключенном js-файле.
И, допустим, мы хотим использовать эту переменную message в коде TypeScript в файле app.ts:
При запуске приложения компилятор TS не сможет скомпилировать программу, так как для кода TS глобальная переменная пока не существует. В этом случае нам надо подключать определение глобальной переменной с помощью декларативных файлов. Для этого добавим в проект новый файл, который назовем globals.d.ts и который будет иметь следующее содержимое:
С помощью ключевого слова declare в программу на TS подключается определение глобальной переменной.
То есть у нас получится следующая структура проекта:
Компиляция
Если мы компилируем, передавая компилятору в консоли название файла:
То в этом случае компилятор не найдет автоматически файл globals.d.ts. В этом случае нам надо в файле app.ts явно указать расположение файла globals.d.ts с помощью директивы reference
Если же мы полагаемся на файл конфигурации tsconfig.json, просто выполняя команду
то директиву /// можно не указывать.
Функции
Пусть на веб-странице в коде js объявлены две следующие функции:
Функция hello() выводит значение переменной message на консоль, а функция sum() возвращает сумму двух чисел.
И, допустим, в коде TS мы хотим вызывать эти функции:
В этом случае подключение в файле globals.d.ts выглядело бы так:
Подключение объектов
Пусть в коде JavaScript есть следующий объект:
Используем этот объект в коде typescript:
В этом случае определение объекта в файле globals.d.ts выглядело бы так:
Подключени сложных объектов
Однако может возникнуть сложность с подключением более сложных объектов. Например, пусть есть такой объект javascript:
Для данного массива объектов в файле globals.d.ts мы можем определить соответствующий отдельному объекту интерфейс и подключить массив объектов некоторого интерфейса, который содержит два свойства X и Y:
И в TS мы сможем использовать этот массив:
Консольный вывод браузера:
Подключение классов
Для этого класса в файле globals.d.ts определим следующее объявление класса:
Для класса прописываем все его поля и методы, при этом методы (в том числе конструктор) не имеют реализации, для них только определяются параметры и их типы и тип возвращаемого значения.
Практическое руководство по TypeScript для разработчиков
Что такое TypeScript?
TypeScript — это популярный статический типизатор (static type checker) или типизированное надмножество (typed superset) для JavaScript, инструмент, разработанный Microsoft и добавляющий систему типов к гибкости и динамическим возможностям JavaScript.
TypeScript развивается как проект с открытым исходным кодом, распространяется под лицензией Apache 2.0, имеет очень активное и высокопрофессиональное сообщество, а также огромное влияние на экосистему JavaScript.
Установка TypeScript
Для того, чтобы начать работу с TypeScript, нужно либо установить специальный интерфейс командной строки (command line interface, CLI), либо воспользоваться официальной онлайн-песочницей или другим похожим инструментом.
Для выполнения кода мы будем использовать Node.js. Устанавливаем его, если он еще не установлен на вашей машине, инициализируем новый Node.js-проект и устанавливаем транспилятор TypeScript:
Это установит tsc (компилятор TypeScript) для текущего проекта. Для того, чтобы проверить установку, в директории проекта создаем файл index.ts следующего содержания:
Затем используем транспилятор для преобразования кода, содержащегося в этом файле, в JavaScript:
Наконец, выполняем скомпилированный код с помощью команды node :
В данном случае транспилятор не делает ничего, кроме копирования кода из одного файла в другой, но это позволяет убедиться, что все установлено и работает правильно.
Определение TypeScript-проекта
tsconfig.json содержит определенное количество настроек, которые влияют на поведение транспилятора, например, на то, какие файлы следует игнорировать, какой файл является целью компиляции, какие типы импортируются и т.д.
Вы легко можете настроить TypeScript с помощью следующей команды:
Сгенерированный tsconfig.json содержит почти все возможные настройки с кратким описанием каждой из них. К счастью, данный файл содержит хорошие настройки по умолчанию, так что вы можете удалить большую часть закомментированных опций.
Мы еще вернемся к настройкам TypeScript, а сейчас давайте писать код.
Возможности TypeScript
Каждая возможность TypeScript подробно рассматривается в «Карманной книге по TypeScript». Мы сосредоточимся на практической составляющей некоторых из них. Я постараюсь пролить свет на некоторые возможности, которые часто упускаются из вида в литературе, посвященной TypeScript.
Основы типизации
Ключевая идея TypeScript заключается в контроле за динамической природой и гибкостью JavaScript с помощью типов. Давайте рассмотрим эту идею на практике.
В директории проекта создаем файл test.js следующего содержания:
Выполняем данный код:
В терминале мы увидим thirty two1 без каких-либо предупреждений об очевидной некорректности вывода. Ничего нового: обычное поведение JavaScript.
Но что если мы хотим обеспечить, чтобы функция addOne() принимала только числа? Вы можете добавить в код проверку типа переданного значения с помощью оператора typeof или же вы можете использовать TypeScript, который привнесет в процесс компиляции кода некоторые ограничения.
Заменим содержимое созданного нами ранее index.ts следующим кодом:
Попытка преобразования проваливается:
Таким образом, определение типов помогает избежать совершения ошибок, таких как передача в функцию аругментов неправильного типа.
Кроме того, TypeScript определяет несколько собственных типов, которые не имеют соответствия в JavaScript, но являются очень полезными с точки зрения используемой в данной экосистеме методологии:
Множества
TypeScript поддерживает несколько типов множеств (обычные массивы, ассоциативные массивы — карты или мапы, кортежи), обеспечивая первоклассную поддержку композиции.
Карты (maps)
Карты, как правило, используются для определения связи между ключами и значениями для представления специфичных для приложения данных:
Векторы (vectors)
Векторы — это последовательная индексированная структура данных, содержащая фиксированные типы для всех элементов. JavaScript не поддерживает данную возможность, но TypeScript позволяет разработчикам эмулировать эту концепцию:
Кортежи (tuples)
Кортежи также являются индексированной структорой данных, но типы элементов могут различаться в зависимости от их позиции:
Объединения (unions)
Другим способом создания композиции типов являются объединения, которые бывают полезны в случаях, когда принимаемый функцией аргумент может иметь один из нескольких типов.
Предположим, что мы хотим создать функцию, возвращающую адрес пользователя на основе переданного объекта или строки.
Затем с помощью typeof осуществляем разделение типов:
Здесь мы в явном виде реализовали предохранитель типов.
К слову, кортежи и объединения можно использовать совместно:
Можно определять размер и тип каждого элемента массива:
Предохранители типов (type guards)
Предохранители типов — это выражения, выполняющие проверки во время выполнения кода, результат которых может быть использован системой типов для сужения (narrow) области (scope) проверяемого аргумента.
Для случаев, когда система типов не может сделать правильный вывод о типе в текущем контексте, мы можем определить пользовательский предохранитель типа через предикат (типизированная функция, возвращающая логическое значение):
Пользовательские предохранители находятся под полным контролем разработчика, TypeScript не имеет возможности убедиться в их корректности.
Весьма распространенным случаем использования пользовательских предохранителей является влидация внешних данных с помощью JSON-схемы, предоставляемой сторонней библиотекой, такой как Ajv. Обычно, это происходит в веб-приложениях, где тело запроса имеет тип unknown (или any в зависимости от используемого фреймворка), и мы хотим проверить его перед использованием:
В основе данного механизма лежит синхронизация JSON-схемы с типом. Если мы изменим тип, но не изменим схему, то вполне можем получить неожиданное сужение типа.
В следующем разделе мы узнаем, как обеспечить автоматическую синхронизацию между схемой и типом.
Исключающие объединения (discriminated unions)
Объединения с общим литеральным полем называются исключающими. При работе с такими типами TypeScript предоставляет неявный предохраитель, позволяя избежать его создания в явном виде:
В функции getFirstProject() TypeScript сужает область аргумента без помощи предиката. Попытка получить доступ к массиву projects в первой ветке (блоке if ) закончится ошибкой типа.
Валидация во время выполнения
Как было отмечено ранее, в случае с пользовательскими предохранителями, корректность возвращаемого результата обеспечивается разработчиком.
При наличии ошибки в предикате, система типов может получить неверную информацию. Рассмотрим пример:
Существует несколько библиотек, которые позволяют обеспечить автоматическую синхронизацию между валидацией во время выполнения и соответствующим типом. Одним из самых популярных решений является runtypes, однако мы будем использовать io-ts и fp-ts.
Суть данного подхода состоит в том, что мы определяем форму (или фигуру) типа с помощью примитивов, предоставляемых io-ts ; эта форма называется декодером (decoder); мы используем ее для проверки данных, которым мы по какой-либо причине не доверяем:
Настройка TypeScript
Данный файл содержит набор ключей и значений, отвечающих за 3 вещи:
Пресеты TSConfig
TypeScript может преобразовывать код в ES3 и поддерживает несколько форматов модулей (CommonJS, SystemJS и др.).
Точные настройки зависят от среды выполнения кода. Например, если вашей целью является Node.js 10, вы можете транспилировать код в ES2015 и использовать CommonJS в качестве стратегии разрешения модулей.
К счастью, команда TypeScript разработала хороший набор пресетов, которые вы можете просто импортировать в свой tsconfig.json :
Среди наиболее важных настроек, можно отметить следующее:
Заключение
Надеюсь, данная статья позволила вам получить общее предствления о возможностях, предоставляемых TypeScript, а также о том, почему использование TypeScript в дополнение к JavaScript в настоящее время фактически является стандартом веб-разработки.
Система типов TypeScript не является идеальной, но это лучшее, что мы имеет на сегодняшний день.
Облачные серверы от Маклауд отлично подходят для сайтов с JavaScript.
Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!
Собеседование по TypeScript: 20 вопросов и ответов
Язык TypeScript основан на том же синтаксисе и семантике, которые хорошо знакомы миллионам JavaScript-разработчиков. TypeScript даёт возможность работать с самыми свежими и ещё только появляющимися возможностями JS, включая те, которые имеются в ECMAScript 2015, и те, которые пока существуют лишь в виде предложений. Среди таких возможностей, например, асинхронные функции и декораторы. Всё это направлено на то, чтобы помочь разработчику в создании надёжных и современных приложений.
TypeScript-программа компилируется в обычный JavaScript-код, который может выполняться в любом браузере или в среде Node.js. Этот код будет понятен любому JS-движку, который поддерживает стандарт ECMAScript 3 или более новый.
Материал, перевод которого мы сегодня публикуем, содержит разбор двадцати вопросов, которые вполне могут задать тому, кто собирается пройти собеседование, претендуя на позицию TypeScript-программиста.
Вопрос №1 (1). Что такое TypeScript и зачем использовать его вместо JavaScript?
В скобках, после номера вопроса, указана его сложность, оцениваемая по пятибалльной шкале.
TypeScript (TS) – это надмножество JavaScript (JS), среди основных особенностей которого можно отметить возможность явного статического назначения типов, поддержку классов и интерфейсов. Одним из серьёзных преимуществ TS перед JS является возможность создания, в различных IDE, такой среды разработки, которая позволяет, прямо в процессе ввода кода, выявлять распространённые ошибки. Применение TypeScript в больших проектах может вести к повышению надёжности программ, которые, при этом, можно разворачивать в тех же средах, где работают обычные JS-приложения.
Вот некоторые подробности о TypeScript:
Вопрос №2 (1). Расскажите об обобщённых типах в TypeScript.
Обобщённые типы (generics) позволяют создавать компоненты или функции, которые могут работать с различными типами, а не с каким-то одним. Рассмотрим пример:
Вопрос №3 (2). Поддерживает ли TypeScript все принципы объектно-ориентированного программирования?
Да, поддерживает. Существуют четыре основных принципа объектно-ориентированного программирования:
Вопрос №4 (2). Как в TypeScript проверять значения на равенство null и undefined?
Для выполнения подобных проверок достаточно воспользоваться следующей конструкцией:
Выражение в скобках будет приведено к true в том случае, если оно не является чем-то из следующего списка:
Вопрос №5 (2). Как в TypeScript реализовать свойства класса, являющиеся константами?
Вопрос №7 (2). Что такое геттеры и сеттеры в TypeScript?
TypeScript поддерживает геттеры и сеттеры, которые позволяют управлять доступом к членам объектов. Они дают разработчику средства контроля над чтением и записью свойств объектов.
Вопрос №8 (2). Можно ли использовать TypeScript в серверной разработке, и если да — то как?
Программы, написанные на TypeScript, подходят не только для фронтенд-разработки, но и для создания серверных приложений. Например, на TS можно писать программы для платформы Node.js. Это даёт программисту дополнительные средства по контролю типов и позволяет использовать другие возможности языка. Для создания серверных приложений на TS нужно лишь наладить правильный процесс обработки кода, на вход которого поступают TypeScript-файлы, а на выходе получаются JavaScript-файлы, подходящие для выполнения их в Node.js. Для того чтобы организовать такую среду, сначала надо установить компилятор TypeScript:
Теперь, при условии, что компилятору есть что обрабатывать, нужно его запустить:
Вопрос №9 (3). Расскажите об основных компонентах TypeScript.
TypeScript включает в себя три основных компонента:
Вопрос №10 (3). Есть ли в предоставленном вам TypeScript-коде ошибки? Объясните свой ответ.
Ошибок в этом коде нет. Объявление класса создаёт две сущности: это тип данных, используемый для создания экземпляров класса, и функция-конструктор. Так как классы создают типы данных, использовать их можно там же, где можно использовать интерфейсы.

Просто очень любим этот фильм )
Вопрос №11 (3). Расскажите об использовании декораторов свойств в TypeScript.
Вопрос №12 (3). Можно ли в TypeScript использовать строго типизированные функции в качестве параметров?
Рассмотрим следующий пример:
Можно ли в методе save организовать работу с типизированным коллбэком? Перепишите код для того, чтобы это продемонстрировать.
В TypeScript можно объявить тип коллбэка, после чего переписать код:
Вопрос №13 (3). Как сделать так, чтобы классы, объявленные в модуле, были бы доступны и за пределами этого модуля?
Классы, объявленные в модуле, доступны в пределах этого модуля. За его пределами доступ к ним получить нельзя.
В коде, приведённом выше, при попытке инициализации переменной fordCar произойдёт ошибка. Для того чтобы сделать класс, объявленный в модуле, доступным за пределами этого модуля, нужно воспользоваться ключевым словом export :
Вопрос №14 (3). Поддерживает ли TypeScript перегрузку функций?
TypeScript поддерживает перегрузку функций, но реализация этого механизма отличается от той, которую можно видеть в других объектно-ориентированных языках. А именно, в TS создают лишь одну функцию и некоторое количество объявлений. Когда такой код компилируется в JavaScript, видимой оказывается лишь одна конкретная функция. Этот механизм работает из-за того, что JS-функции можно вызывать, передавая им разное количество параметров.
Вопрос №15 (4). Что не так с предоставленным вам кодом?
Вот код, о котором идёт речь:
Вопрос №16 (4). Как в TypeScript перегрузить конструктор класса?
TypeScript позволяет объявлять множество вариантов методов, но реализация может быть лишь одна, и эта реализация должна иметь сигнатуру, совместимую со всеми вариантами перегруженных методов. Для перегрузки конструктора класса можно воспользоваться несколькими подходами:
Вопрос №17 (4). Чем различаются ключевые слова interface и type в TypeScript?
Вот примеры использования этих ключевых слов:
В отличие от объявления интерфейса, которое всегда представляет именованный тип объекта, применение ключевого слова type позволяет задать псевдоним для любой разновидности типа, включая примитивные типы, типы-объединения и типы-пересечения.
При использовании ключевого слова type вместо ключевого слова interface теряются следующие возможности:
Вопрос №18 (5). Расскажите о том, когда в TypeScript используют ключевое слово declare.
Ключевое слово declare используется в TypeScript для объявления переменных, источником которых может служить некий файл, не являющийся TypeScript-файлом.
И в том и в другом случае при компиляции TS-кода в JavaScript, получится одно и то же, но вариант с использованием ключевого слова declare отличается лучшей читабельностью. Применение этого ключевого слова приводит к созданию так называемого внешнего объявления переменной (ambient declaration).
Вопрос №19 (5). Что такое внешние объявления переменных в TypeScript и когда их нужно использовать?
Внешнее объявление переменной (ambient declaration) — это механизм, который позволяет сообщать компилятору TypeScript о том, что некий исходный код существует где-то за пределами текущего файла. Внешние объявления помогают интегрировать в TS-программы сторонние JavaScript-библиотеки.
Файлы, в которых находится внешний код, должны быть подключены в TS-файле, использующем их, так:
Вопрос №20 (5). Можно ли автоматически генерировать файлы объявлений TypeScript из JS-библиотек?
JavaScript не всегда содержит достаточно информации, которая позволяет TypeScript автоматически выводить типы. Поэтому практически невозможно автоматически создавать объявления типов, основанные на JavaScript. Однако можно попытаться это сделать, воспользовавшись следующими инструментами:
Итоги
Надеемся, разбор приведённых в этом материале вопросов поможет вам лучше узнать TypeScript, возможно, обратить внимание на то, на что раньше вы внимания не обращали, и, если вы готовитесь к собеседованию, повысит ваши шансы на его успешное прохождение.
Уважаемые читатели! Какие вопросы вы задали бы тому, кто проходит собеседование, претендуя на должность, требующую знания TypeScript?

— И какая скидка по этому промо-коду?!
— Кажется, 7%. Проверю, если хотите…
— Да уж, вы проверьте. По-моему, скидка чуть завышена!
…
— Простите, я немного ошиблась насчет скидки. 10% на все виртуальные сервера.
TypeScript
TypeScript — язык программирования, представленный Microsoft в 2012 году и позиционируемый как средство разработки веб-приложений, расширяющее возможности JavaScript.
Разработчиком языка TypeScript является Андерс Хейлсберг (англ. Anders Hejlsberg), создавший ранее Turbo Pascal, Delphi и C#.
TypeScript является обратно совместимым с JavaScript и компилируется в последний. Фактически, после компиляции программу на TypeScript можно выполнять в любом современном браузере или использовать совместно с серверной платформой Node.js. Код экспериментального компилятора, транслирующего TypeScript в JavaScript, распространяется под лицензией Apache. Его разработка ведётся в публичном репозитории через сервис GitHub.
TypeScript отличается от JavaScript возможностью явного статического назначения типов, поддержкой использования полноценных классов (как в традиционных объектно-ориентированных языках).
tsconfig. json представляет собой стандартный файл в формате json, который содержит ряд секций. Например:
Таблица типов в Typescript
TypeScript является строго типизированным языком, и каждая переменная и константа в нем имеет определенный тип. При этом в отличие от javascript мы не можем динамически изменить ранее указанный тип переменной.
В TypeScript имеются следующие базовые типы:
Type assertion
Type assertion представляет модель преобразования значения переменной к определенному типу. Обычно в некоторых ситуациях одна переменная может представлять какой-то широкий тип, например, any, который по факту допускает значения различных типов. Однако при этом нам надо использовать переменную как значение строго определенного типа. И в этом случае мы можем привести к этому типу.
Есть две формы приведения. Первая форма заключается в использовании угловых скобок:
Вторая форма заключается в применении оператора as:
Jenerics
TypeScript является строго типизированным языком, однако иногда надо построить функционал так, чтобы он мог использовать данные любых типов. В некоторых случаях мы могли бы использовать тип any:
Однако в этом случае мы не можем использовать результат функции как объект того типа, который передан в функцию. Для нас это тип any. Если бы вместо числа 5 в функцию передавался бы объект какого-нибудь класса, и нам потом надо было бы использовать этот объект, например, вызывать у него функции, то это было бы проблематично. И чтобы конкретизировать возвращаемый тип, мы можем использовать обобщения:
Utility Types
Typescript поставляет объекты при помощи которых можно легко проводить трансформацию типов, например:
Requared — создаёт тип, в котором все поля обязательные
Readonly — все поля не могут быть изменены
ReturnType — Создает тип, состоящий из типа, возвращаемого функцией Type.
Декларации¶
Декларации это очень важная часть TypeScript благодаря которой магия статической типизации проецируется на динамический JavaScript. Поэтому декларациям будет посвящена вся данная глава, рекомендуемая тем, кто только собирается писать свою первую типизированную библиотеку, которую планируется распространять с помощью npm репозитория.
Что такое декларация (Declaration)¶
Поскольку при разработке программ на TypeScript используются библиотеки написанные на JavaScript, компилятор tsc, чьей главной задачей является проверка типов, чувствует себя будто у него завязаны глаза. Несмотря на то, что с каждой новой версией вывод типов все лучше и лучше учится разбирать JavaScript, до идеала ещё далеко. Кроме того, разбор JavaScript кода добавляет нагрузку на процессор, драгоценного время которого при разработке современных приложений, порой и так не достаточно.
Еще не забыты дни, когда для часто используемых библиотек приходилось писать декларации вручную, при чем они часто содержали ошибки. Кроме этого, декларации не успевали обновляться под постоянно развивающиеся библиотеки. Сейчас такие проблемы кажутся уже нереальными, но несмотря на это, до сих пор приходится прибегать к использованию менеджера деклараций, который был создан в те самые далекие времена.
Установка деклараций с помощью @types¶
Если декларация распространяется отдельно от библиотеки, то она скорее всего, попадет в огромный репозиторий на github под названием DefinitelyTyped содержащий огромное количество деклараций. Чтобы было проще ориентироваться в этом множестве, помимо сайта «TypeSearch» выступающего в роли поисковика, был создан менеджер деклараций под названием Typed. Но о нем мы говорить не будем поскольку он применяется при работе с TypeScript версии меньше чем v2.0, поэтому речь пойдет о его развитии в образе команды пакетного менеджера npm, а именно @types.
Для примера, воспользуемся проектом созданным в теме посвященной настройки рабочего окружения и для демонстрации работы директивы @types установим всем известную библиотеку React.
Первым делом установим саму библиотеку React выполнив в терминале, запущенным из-под директории проекта, следующую команду.
Но для полноты картины и этого недостаточно. Для того чтобы добавить наш компонент в dom-дерево, необходимо установить ReactDOM, который уже давно развивается отдельной библиотекой.
Кроме того, нужно установить необходимую для работы с ним декларацию.
Подготовка к созданию декларации¶
Это в свою очередь означает, что при импорте модулей придется учитывать лишнюю директорию.
Поэтому решений у этой проблемы, на самом деле, всего два. Задавать идентификаторы отличающиеся не только регистром. Или же размещать файлы таким образом, чтобы их идентификаторы не пересекались в одной директории. Но при этом нужно помнить, что структура модулей также изменится.
И поскольку TypeScript является компилируемым языком, не будет лишним напомнить правила именования директории в которую будет компилироваться результат. В случае разработки приложения, директорию содержащую скомпилированный результат принято называть dest (сокращение от слова destination). При разработке внешней библиотеки или фреймворка, директорию для собранных файлов принято называть dist (сокращение от слова distributive).
Разновидности деклараций¶
На самом деле это глава должна называться «разновидности библиотек», так как именно о них и пойдет речь. Дело в том, что совсем недавно вершиной хорошего тона считалось объединение всего кода в один файл. Это же правило соблюдалось и при создании библиотек. Но сейчас все кардинально поменялось, и дело вот в чем.
В мире JavaScript существует большое количество библиотек, чей размер по меркам клиентских приложений превышает разумный. При этом отказ от них будет означать, что вам самому придется тратить драгоценное время на реализацию части их функционала. Это побудило создателей сборщиков наделять свои творения механизмом называющимся Tree Shaking.
Tree Shaking — это механизм позволяющий включать в сборку исключительно используемый код. Простыми словами, данный механизм позволяет взять только используемую часть от всей библиотеки. В перспективе это должно быть спасением, но на деле оказалось не совсем так.
Дело в том что на данный момент Tree Shaking работает только если библиотека разбита на множество модулей. К примеру такие именитые библиотеки, как lodash или rxjs, для каждой отдельной функции создают отдельную точку входа что при их использовании позволят значительно сократить размер конечного кода. Обозначим подобные библиотеки, как библиотеки с множеством точек входа. Кроме того существуют библиотеки сопоставимые с монолитом, поскольку при использовании их малой части в конечную сборку они попадают целиком. Обозначим такие библиотеки, как библиотеки с единственной точкой входа.
Декларации и область видимости¶
Если не уделить должного внимания области видимости при создании деклараций для подключаемых библиотек у разработчиков которые будут использовать подобные декларации с другими декларациями имеющими идентичное определение, могут возникнуть ошибки на этапе компиляции. Решений у этой проблемы всего два — сокрытие определений и уточнение определений. Способ к которому стоит прибегнуть зависит от вида разрабатываемой библиотеки.
Декларации для библиотек с одной точкой входа¶
В коде нет ничего необычного, поэтому комментариев не будет. Если кому-то содержимое файла index.lib.ts показалось необычным, то стоит отметить, что это обычный ре-экспорт модулей JavaScript, который никакого отношения к TypeScript не имеет. Повторю, файл index.lib.ts является точкой входа создаваемой библиотеки, поэтому он должен экспортировать все то, что может потребоваться при работе с ней. Конкретно в этом случае экспортировать utils наружу не предполагается, поэтому они не были реэкспортированы.
Также стоит обратить внимание на конфигурационные файлы TypeScript, которые взаимно добавляют точки входа друг друга в исключение. Кроме того, конфигурационный файл dev-сборки исключает также конфигурационный файл prod-сборки.
Судить, какой из этих вариантов лучше, я не возьмусь, так как на мой взгляд, в данный момент, они оба не являются исчерпывающими. Возможно в будущем появятся новые правила для создания деклараций или редакторы будут по другому обрабатывать эти.
Также стоит обратить внимание, что в случае компиляции при помощи tsc, если в конечной директории присутствуют файлы, чьи имена совпадают с именами генерируемых при компиляции файлов, несмотря на их замену, ошибка все равно возникнет. Другими словами, если процесс сборки запускается не в первый раз, то нужно удалить файлы оставшиеся от предыдущей компиляции.
Декларации для библиотек с множеством точек входа¶
При разработке библиотеки имеющий множество самостоятельных частей более разумно создавать каждую часть в виде отдельной точки входа. Это позволит использующим её приложениям за счет подключения только необходимых частей минимизировать вес конечной сборки, что становится возможно благодаря механизму Tree Shaking.
Стоит сказать что конфигурационные файлы ничем не отличаются от рассмотренных в теме создания деклараций для библиотек с одной точкой входа, поэтому их описание будет опущено.
Сразу следует сказать что с подобным описанием декларация не будет правильно функционировать, поэтому её придется подправить руками до следующего вида.
Обычно, как отдельную часть принято экспортировать только самодостаточные модули, такие как функции или классы. Но кроме того могут потребоваться объекты содержащие константы или что-то незначительное, без чего отдельный модуль не сможет функционировать. Если такие объекты используются всеми самостоятельными модулями, то их можно также вынести в отдельный самостоятельный модуль. В случае, когда самодостаточному модулю для полноценной работы требуются зависимости, которые больше никем не используются, то такой модуль нужно оформлять также как обычную точку входа. Другими словами он должен содержать ре-экспорт всего необходимого. А кроме того экспортировать все как глобальный namespace с помощью синтаксиса:
Создание деклараций вручную¶
Директива с тройным слешем (triple-slash directives)¶
Кроме того с помощью данной директивы можно указать версию используемой библиотеки.





