Комплексное руководство по легкому переходу и эффективному управлению ошибками

Если вы открыли это, возможно, вы уже знаете, что TypeScript — это надмножество JavaScript и что TypeScript в конечном итоге переводится в JavaScript, чтобы его можно было запускать в браузерах.

Возникает вопрос: зачем кому-то переходить на TS?

Зачем это делать?

Существует несколько причин, по которым может возникнуть желание преобразовать свой проект JavaScript в TypeScript, наиболее очевидной из которых является возможность выявлять ошибки во время кодирования, а не на этапе компиляции (особенно полезно для проектов, в которых каждое развертывание занимает много времени).

Кроме того, хотя размер, объем и сложность программ, написанных на JavaScript, выросли в геометрической прогрессии, способность языка JavaScript выражать отношения между различными единицами кода не изменилась. В сочетании с довольно своеобразной семантикой времени выполнения JavaScript это несоответствие между языком и сложностью программы сделало разработку JavaScript сложной задачей для управления в масштабе.

TypeScript может помочь вам устранить это несоответствие, предоставляя функции ООП, которые помогут вам моделировать более четкие связи между различными частями вашего кода.

Не для всех

Имейте в виду, что вышеизложенное обычно применимо только к новым проектам, поскольку преобразование большого проекта, написанного с использованием парадигмы функционального программирования, в структуру, основанную на классах ООП, требует много времени и ресурсов, настолько, что вам лучше написать весь проект целиком. вещь с нуля.

В любом случае, теперь, когда вы здесь, всегда полезно убедиться, что вы делаете это по правильным причинам.

Вот несколько веских причин для перехода на TypeScript:

  • Использование аннотаций типов
  • Функции языка, предоставляемые поверх JavaScript
  • Расширенный IntelliSense
  • Отличная документация по API

И некоторые не очень хорошие причины для перехода:

  • Думаю, что это проще, чем JavaScript
  • Предполагая, что правильность типа === корректность программы
  • Все так делают

Обзор процесса

Приведенные ниже шаги вкратце проведут вас через весь процесс. В конце также есть руководство по исправлению распространенных ошибок, с которыми вы можете столкнуться, когда начнете конвертировать файлы TS в JS.

  • Создайте две папки: src и build. Скопируйте/вставьте все старые файлы проекта в папку src.
    — Удалите package.json и любые другие файлы, не связанные с конфигурацией JS (папка .github, файлы .gitignore, webpack, gulp и т. д.) в корневой каталог.
  • Установите TypeScript, выполнив npm install typescript. И используйте команду tsc --init для создания файла tsconfig.json.
  • tsconfig.json должен иметь определенные входные и выходные каталоги, должен позволять первоначальную обработку JS и должен включать целевую версию JS. В целом в файле должны присутствовать следующие параметры:
{
"compilerOptions": {
    "outDir": "./build",
    "allowJs": true,
    "target": "es5"
},
"include": ["./src/**/*"]
}
  • На этом этапе запуск tsc будет искать любые файлы с расширением .ts или .js (из-за разрешенияJs) и переносить их в папку сборки. Но он не обрабатывает другие файлы, такие как html, ejs или css в нашем проекте.

Как обрабатывать файлы, отличные от JS?

Есть два способа справиться с тем, что происходит с файлами, отличными от JS, которые не транспилируются самим компилятором TS.

Вы можете использовать инструменты сборки, такие как webpack или gulp, чтобы обрабатывать эти файлы за вас. Для этого существует официальное руководство, к которому вы можете обратиться.

В противном случае для проектов, не интегрирующих инструменты сборки, вы можете использовать следующую созданную мной собственную логику многократного использования:

В этом методе используются библиотеки ts-node, shelljs, nodemon, rimraf и npm-run-all.

  • Установите все вышеупомянутые пакеты и определения их типов.
  • Создайте папку с именем Tools и файл с именем copy-assets.ts в ней. Используйте файл для копирования ресурсов (папки представлений и т. д.) из src для сборки с помощью модуля Shelljs.
import * as shell from "shelljs";

// Copy all the view templates
shell.cp("-R", "src/views", "build/");

// add commands for any other stuff to copy over
  • Добавьте эти скрипты в package.json:
"scripts": {    // remove comments if you copy this as json doesn't support comments
    "clean": "rimraf build/*",  // deletes everything from build
    "tsc": "tsc",   // transpiles typescript to javascript
    "copy-assets": "ts-node tools/copyAssets",  // copies relevant assets from src to build
    "build": "npm-run-all clean tsc copy-assets",   // runs all of the above mentioned scripts with a single command
    "start": "node .",  // command to run dev server
    "dev:start": "npm-run-all build start",    // transpiles and then starts the dev server
    "dev": "nodemon --watch src -e ts,ejs,png,css --exec npm run dev:start",    // starts the dev server in watch mode
}
  • В package.json измените основную точку входа приложения, а также укажите свойство files, чтобы включать только файлы папки сборки.
"main": "build/index.js",
  "files": [
    "build/**/*.*",
    "package.json"
  ]

Теперь вы готовы преобразовать свой первый файл JS в TS!

Фактический процесс преобразования:

Выберите любой файл (попробуйте начать с файлов меньшего размера и действовать в том же порядке, что и ваше приложение [т. е. для экспресс-приложения: index.js -> маршрутизатор -> промежуточное программное обеспечение -> обработчик]), который вы хотите преобразовать, и измените его расширение на .ts. Устраните любую ошибку, которая может возникнуть: приведенное ниже руководство проливает свет на некоторые распространенные ошибки, с которыми вы можете столкнуться. После устранения ошибок запустите npm run build. Он должен скопировать машинописный код и дать желаемый результат.

Повторяйте процесс, пока все файлы проекта не будут преобразованы в TS. Если возможно, запускайте проект после каждого преобразования: это облегчит обнаружение любых ошибок, допущенных вами во время преобразования, и поможет изолировать причину сбоя в этом единственном недавно преобразованном файле.

Распространенные ошибки и их исправления:

Ниже приведены некоторые ошибки, с которыми обычно приходится сталкиваться при преобразовании кода JavaScript в TypeScript.

- › Ошибка № 1: при попытке транспиляции с помощью команды tsc вы получаете No inputs were found in config file.

Ошибка означает, что TS не удалось найти файл для компиляции. Создайте пустой файл .ts в папке src или преобразуйте любой существующий файл .js, и ошибка должна исчезнуть.

- › Ошибка № 2: Could not find a declaration file for module 'module-name'.

Ошибка означает, что аннотации типов для этого модуля отсутствуют, поэтому мы можем легко это исправить, выполнив npm install -D @types/module-name

- › Ошибка №3: ​​File is not a module

Способ экспорта/импорта файлов машинописного текста отличается от способа импорта файлов JavaScript. Например, вы импортируете модуль с помощью const xyz = require("xyz");, то же самое можно сделать в машинописном тексте следующими способами: javascript import * as app1 from "./test"; import app2 = require("./test"); import {App} from "./test";. Аналогично, для экспорта вы конвертируете module.exports = foo в export = foo. Подробности здесь.

- › Ошибка № 4: Element implicitly has an 'any' type

Возможно, это самая распространенная ошибка, с которой вы можете столкнуться при преобразовании файла JS в TS. Это означает, что машинописный текст не знает тип «Элемента» и присвоил ему общий тип any и, следовательно, не может предоставить вам своего рода интеллектуальную информацию или отчеты об ошибках. Вы можете решить эту проблему, присвоив элементу тип, будь то примитивный тип, например string, или определяемый пользователем interface

- › Ошибка №5: Object is possibly 'undefined'

Вы можете столкнуться с этим, если пытаетесь получить доступ к какому-либо вложенному свойству объекта. В ошибке говорится, что ни вы, ни машинописный текст не можете знать, будет ли это свойство существовать во время выполнения, поэтому вам нужно обработать случай, когда оно не существует. Есть довольно простое решение этой проблемы: просто добавьте «?» к каждому свойству, которое может быть неопределенным, и TS автоматически обработает и назначит неопределенное значение в случае, если оно не существует. Пример: const data = change?.in?.data();

- › Ошибка №6: Typescript Error: Property 'abc' does not exist on type 'XYZ'

Это означает, что «abc» не является свойством, которое изначально доступно в объекте XYZ используемой вами библиотеки. Если вы уверены, что что-то (например, промежуточное ПО) добавляет такое свойство к объекту XYZ, вы можете переопределить тип XYZ следующим образом:

declare module "module-name" { 
  export interface XYZ {
    abc: string,
  }
}

- › Ошибка №7: Object is of type 'unknown'.

Typescript присваивает неизвестную ошибку в блоке catch команды try/catch, поскольку не знает, какой тип ошибки может быть выдан. Как разработчик, вы должны немного помочь машинописному тексту и сообщить ему тип ошибки, чтобы он мог выполнять свою работу. Например, если вы выполняете вызов API, вы, скорее всего, получите либо StatusCodeError, либо RequestError. Итак, вы можете обработать ошибку следующим образом:

try {
    perform some task
} catch(err) {
     if (err instanceof StatusCodeError) 
     { 
         handle server/auth error   // typescript is intelligent enough to only show you properties that are available on a Status Code Error here
     } else if (err instanceof RequestError) 
     { 
         handle bad request error   // can access all Request Error properties here
     }
}

- › Ошибка № 8: 'Foo' only refers to a type, but is being used as a value here.

Если переменная может иметь разные типы значений в зависимости от сценария, вы можете использовать instanceof для обработки каждого из сценариев. Именно здесь обычно можно увидеть вышеуказанную ошибку. Для решения этой проблемы вам может потребоваться использовать Type Guards. Подробности здесь.

- › Ошибка № 9: No overload matches this call.

Происходит, когда вы передали неправильное количество аргументов анонимной функции. Например, вы можете увидеть эту ошибку при добавлении промежуточного программного обеспечения в экспресс. Для этого можно использовать утверждение типа (as), чтобы сообщить машинописному тексту, что вы пытаетесь сделать. например.; Router.get("/work", module.doSomeWork as unknown as express.RequestHandler);

Последние мысли

Опираясь на свой собственный опыт, я могу с уверенностью утверждать, что переход с JavaScript на TypeScript может изменить правила игры для ваших проектов. Используя возможности TypeScript, вы не просто переносите код, но и используете новый подход к разработке. Это руководство провело вас через весь процесс: от понимания причин перехода до устранения распространенных камней преткновения. Итак, независимо от того, привлекает ли вас обещание обнаружения ошибок во время написания кода или заинтригован потенциалом более четких взаимосвязей в коде, переход на TypeScript имеет потенциал изменить то, как вы создаете свои цифровые творения. Приятного кодирования!

Спасибо, что подписались! Если это вам помогло, пожалуйста, подумайте о том, чтобы купить мне кофе!

А еще, если вы хотите получать уведомления о моих будущих историях, подпишитесь.