Использование возможностей TypeScript в JavaScript без написания TypeScript-кода

в 9:30, , рубрики: javascript, TypeScript, Блог компании RUVDS.com, разработка, Разработка веб-сайтов

Я — большой любитель TypeScript. По возможности я стараюсь использовать этот язык в своих проектах. TypeScript даёт разработчику отчёты об ошибках и проверку типов в JavaScript и TypeScript-коде. Кроме того, тот, кто пишет на TypeScript, может пользоваться удобными возможностями по автозавершению кода, может, быстро и надёжно, выполнять рефакторинг. TypeScript — это первая линия обороны от ошибок в коде. Ещё одна сильная сторона этого языка заключается в том, что он позволяет, при написании программ, пользоваться самыми свежими возможностями JavaScript. При этом то, что получается при преобразовании TypeScript-кода в JavaScript, будет поддерживаться всеми браузерами. Это очень приятно.

Использование возможностей TypeScript в JavaScript без написания TypeScript-кода - 1

Правда, не все фронтенд-проекты предусматривают применение TypeScript. Что если можно было бы пользоваться возможностями TypeScript, но при этом не переводить на него весь проект (и всю команду), и не добавлять в конвейер сборки проекта новый инструмент? Это возможно благодаря VS Code и JSDoc.

Настройка рабочей среды

▍Вариант №1. Настройки VS Code (глобальная проверка)

Первый способ использования TypeScript (TS) в проектах, написанных на обычном JavaScript (JS), заключается в том, чтобы применять TS для проверки всех JS-файлов. Делается это посредством включения одного глобального параметра VS Code. Этот параметр можно включить в настройках пользователя или рабочего пространства:

"javascript.implicitProjectConfig.checkJs": true

Если вы из тех, кто предпочитает пользоваться графическим интерфейсом, то включить это можно так, как показано ниже.

Использование возможностей TypeScript в JavaScript без написания TypeScript-кода - 2

Включение проверки 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) {
    ...
}

После этого редактор сможет выдавать подсказки по типам.

Использование возможностей TypeScript в JavaScript без написания TypeScript-кода - 3

Подсказка по типу значения, принимаемого функцией

Этот метод хорошо подходит для простых типов, но что если разработчику нужно описывать собственные типы? Сделать это можно с помощью тега @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-комментариев.

Использование возможностей TypeScript в JavaScript без написания TypeScript-кода - 4

Типизация обычной переменной

▍Типизация библиотек

В 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?

Использование возможностей TypeScript в JavaScript без написания TypeScript-кода - 5

Автор: ru_vds

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js