Я — большой любитель TypeScript. По возможности я стараюсь использовать этот язык в своих проектах. TypeScript даёт разработчику отчёты об ошибках и проверку типов в JavaScript и TypeScript-коде. Кроме того, тот, кто пишет на TypeScript, может пользоваться удобными возможностями по автозавершению кода, может, быстро и надёжно, выполнять рефакторинг. TypeScript — это первая линия обороны от ошибок в коде. Ещё одна сильная сторона этого языка заключается в том, что он позволяет, при написании программ, пользоваться самыми свежими возможностями JavaScript. При этом то, что получается при преобразовании TypeScript-кода в JavaScript, будет поддерживаться всеми браузерами. Это очень приятно.
Правда, не все фронтенд-проекты предусматривают применение TypeScript. Что если можно было бы пользоваться возможностями TypeScript, но при этом не переводить на него весь проект (и всю команду), и не добавлять в конвейер сборки проекта новый инструмент? Это возможно благодаря VS Code и JSDoc.
Настройка рабочей среды
▍Вариант №1. Настройки VS Code (глобальная проверка)
Первый способ использования TypeScript (TS) в проектах, написанных на обычном JavaScript (JS), заключается в том, чтобы применять TS для проверки всех JS-файлов. Делается это посредством включения одного глобального параметра VS Code. Этот параметр можно включить в настройках пользователя или рабочего пространства:
"javascript.implicitProjectConfig.checkJs": true
Если вы из тех, кто предпочитает пользоваться графическим интерфейсом, то включить это можно так, как показано ниже.
Включение проверки JS-кода средствами TypeScript
▍Вариант №2. Использование файла jsconfig.json (глобальная проверка)
Ещё один вариант включения глобальной проверки JS-кода средствами TS заключается в использовании файла jsconfig.json
. Если такой файл имеется, настройки, заданные в нём, переопределят настройки, заданные в VS Code.
{
"compilerOptions": {
"checkJs": true
}
}
▍Вариант №3. Включение проверки для отдельных файлов
Третий способ использования TypeScript для контроля JS-кода предназначен для включения проверки на уровне отдельных файлов. Он заключается в добавлении в начало файла соответствующего комментария:
// @ts-check
let itsAsEasyAs = 'abc';
itsAsEasyAs = 123; // Error: Type '123' is not assignable to type 'string'
Используя ту же идею, можно выключить TS-проверку для отдельного JS-файла. Делается это в том случае, если TS-проверка включена глобально с использованием вышеописанных способов. Тут тоже используется специальный комментарий:
// @ts-nocheck
let easy = 'abc';
easy = 123; // ошибки нет
А если надо, чтобы TypeScript игнорировал бы лишь часть файла, можно поступить так:
let easy = 'abc';
// @ts-ignore
easy = 123; // ошибки нет
Типизация кода с использованием JSDoc
Только что мы поговорили о том, как включать TS-проверку на уровне файлов. Это даёт базовые возможности по проверке типов. Их можно расширить, описывая типы с помощью комментариев формата JSDoc.
▍Типизация функций
Начать типизацию кода средствами JSDoc можно с описания того, что функции принимают на вход:
/**
* @param {number} shippingVal
*/
updateShipping(shippingVal) {
...
}
После этого редактор сможет выдавать подсказки по типам.
Подсказка по типу значения, принимаемого функцией
Этот метод хорошо подходит для простых типов, но что если разработчику нужно описывать собственные типы? Сделать это можно с помощью тега @typedef
. Рекомендую помещать описания типов в начале файла. Это облегчит обнаружение таких описаний в ходе работы:
/**
* @typedef {Object} CreditNoteTaxResponseViewModel
* @property {number} feeAmount
* @property {number} inclGst
* @property {number} subTotal
* @property {number} total
*
* @typedef {Object} ApiResponse
* @property {string} status
* @property {string} message
* @property {CreditNoteTaxResponseViewModel} response
*/
Такие описания можно использовать там, где это нужно:
/**
* @param {CreditNoteTaxRequestViewModel} req
* @returns {Promise<ApiResponse>}
*/
createCreditNoteTaxApiCall(req) {
...
}
Ещё один вариант применения этой методики заключается в перемещении объявлений типов в особые файлы. Скажем, такой файл может называться main.d.ts
.
export interface ICreditNoteTaxRequestViewModel{
orderID: number;
shippingCredit: number;
lines: IICreditNoteTaxLineViewModel[]
}
export interface ICreditNoteTaxLineViewModel{
originalOrderLineID:number;
creditQuantity: number;
}
export interface ICreditNoteTaxResponseViewModel{
feeAmount: number;
inclGst: number;
subTotal: number;
total: number;
}
export interface IApiResponse{
status: string;
status: message;
response: ICreditNoteTaxResponseViewModel;
}
Эти типы потом можно использовать в JavaScript:
/**
* @param {import("./main").ICreditNoteTaxRequestViewModel} req
* @returns {Promise<import("./main").IApiResponse>}
*/
function createCreditNoteTaxApiCall(req) {
/// некие действия
return;
}
▍Типизация обычного кода
Вышеприведённые примеры решают задачу типизацию входных и выходных значений функций. Нечто подобное можно делать и с помощью встроенных в код JSDoc-комментариев.
Типизация обычной переменной
▍Типизация библиотек
В VS Code есть система автоматического получения типов для сторонних библиотек. Соответствующая процедура применяется ко всем пакетам, описанным в файле package.json
. Но, если кто-то предпочитает задавать подобное в явном виде, он может внести соответствующие настройки в jsconfig.json
:
{
"typeAcquisition": {
"include": ["jquery"]
}
}
После того, как система получения типов обработает библиотеку, типы можно будет использовать в JSDoc:
/**
* @param {JQuery<HTMLElement>} $itemRow
*/
initRow($itemRow) {
...
}
Переход на TypeScript
Если вы решили перевести на TypeScript JavaScript-проект, в некоторых частях которого используется TypeScript, можно просто переименовать jsconfig.json
в tsconfig.json
и включить в нём параметр allowJs
:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true
}
}
После этого можно приступать к переименованию *.js
-файлов в *.ts
-файлы и к типизации кода этих файлов. Процесс перевода проекта на TypeScript может происходить постепенно.
Итоги
Прочтя этот материал, вы могли заметить то, как легко воспользоваться возможностями TypeScript в JavaScript-проекте. Для этого нужно лишь соответствующим образом настроить VS Code. Описанный здесь подход позволяет не вносить никаких изменений в процесс сборки проекта, не рисковать нарушением этого процесса, не принуждать команду разработчиков к срочному переходу на новый язык.
Если же JS-проект, в котором используются лишь некоторые возможности TypeScript, решено будет полностью перевести на TS, сделать это тоже несложно. К тому же, такой переход можно осуществлять поэтапно.
Вот GitHub-репозиторий, в котором можно найти примеры кода, использованные в этой статье.
Уважаемые читатели! Как вы относитесь к идее проверки типов в JS-коде с использованием возможностей TypeScript?
Автор: ru_vds