![](https://habrastorage.org/webt/hf/n7/xv/hfn7xvpemklcokkja72y6oyvp7q.png)
Правда, не все фронтенд-проекты предусматривают применение TypeScript. Что если можно было бы пользоваться возможностями TypeScript, но при этом не переводить на него весь проект (и всю команду), и не добавлять в конвейер сборки проекта новый инструмент? Это возможно благодаря VS Code и JSDoc.
Настройка рабочей среды
?Вариант №1. Настройки VS Code (глобальная проверка)
Первый способ использования TypeScript (TS) в проектах, написанных на обычном JavaScript (JS), заключается в том, чтобы применять TS для проверки всех JS-файлов. Делается это посредством включения одного глобального параметра VS Code. Этот параметр можно включить в настройках пользователя или рабочего пространства:
"javascript.implicitProjectConfig.checkJs": true
Если вы из тех, кто предпочитает пользоваться графическим интерфейсом, то включить это можно так, как показано ниже.
![](https://habrastorage.org/getpro/habr/post_images/dc7/3d9/9c1/dc73d99c145237f8ccf22ce1a6b3a751.png)
Включение проверки 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) {
...
}
После этого редактор сможет выдавать подсказки по типам.
![](https://habrastorage.org/getpro/habr/post_images/3b8/cb6/fbd/3b8cb6fbd8c6126a3c4248b4feee6b49.png)
Подсказка по типу значения, принимаемого функцией
Этот метод хорошо подходит для простых типов, но что если разработчику нужно описывать собственные типы? Сделать это можно с помощью тега
@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-комментариев.
![](https://habrastorage.org/getpro/habr/post_images/a3f/ef2/3c6/a3fef23c6f3f2d8dd742304531a2a20a.png)
Типизация обычной переменной
?Типизация библиотек
В 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?
![](https://habrastorage.org/files/1ba/550/d25/1ba550d25e8846ce8805de564da6aa63.png)
Zamuka
Уже несколько месяцев пользуюсь при работе с легаси проектом. Все надеюсь, что исправлю все ошибки типизации и включу проверку с помощью tsc в билд.
Кроме кучи ошибок, которые страшно трогать не смог побороть привязку интерфейса из .d.ts к классу. @implements не подхватывается.
А вообще — отлично.
Не надо ничего переименовывать, можно оставить все в js, только сказать, чтоб tsc никуда не компилировал — будет только проверять
Забыл сказать, что подсветка ошибок работает не только в VSCode но и в шторме, хотя немного разное поведение * и any