Spec-Zone.ru › Deno 2

Настройка TypeScript

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

Проверка типов JavaScript

Возможно, вы захотите сделать свой JavaScript более типобезопасным, не добавляя аннотации типов повсюду. Deno поддерживает использование TypeScript type checker для проверки типов JavaScript. Вы можете отметить отдельные файлы, добавив в них прагму проверки JavaScript:

// @ts-check

Это заставит type checker определить информацию о типах JavaScript-кода и вывести любые проблемы как диагностические сообщения.

Эти проверки можно включить для всех JavaScript-файлов в программе, предоставив файл конфигурации с опцией check JS, установленной в значение true, как показано ниже. Затем используйте опцию --config при запуске в командной строке.

{
  "compilerOptions": {
    "checkJs": true
  }
}

Использование JSDoc в JavaScript

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

Например, чтобы установить тип массива, используйте следующий JSDoc-комментарий:

/** @type {string[]} */
const a = [];

Пропуск проверки типов

Возможно, у вас есть код TypeScript, с которым вы экспериментируете, где синтаксис верен, но не полностью типобезопасен. Вы можете обойти проверку типов для всей программы, передав флаг --no-check.

Вы также можете пропустить проверку типов целых файлов, включая JavaScript, если у вас включена опция check JS, используя прагму nocheck:

// @ts-nocheck

Переименование файлов JS в TS-файлы

TypeScript-файлы извлекают выгоду из возможности TypeScript-компилятора проводить более тщательную проверку безопасности вашего кода. Это часто называют строгим режимом. Когда вы переименовываете файл .js в файл .ts, вы можете увидеть новые ошибки типов, которые TypeScript ранее не мог обнаружить.

Настройка TypeScript в Deno

TypeScript предлагает множество опций конфигурации, что может быть ошеломляющим, если вы только начинаете работать с TS. Deno стремится упростить использование TypeScript, вместо того, чтобы завалить вас бесчисленными настройками. Deno настраивает TypeScript для работы из коробки. Дополнительные головные боли с конфигурацией не требуются!

Однако, если вы хотите изменить параметры компилятора TypeScript, Deno позволяет вам сделать это в файле deno.json. Укажите путь в командной строке или используйте значение по умолчанию. Например:

deno run --config ./deno.json main.ts
Примечание

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

Параметры компилятора TS

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

Параметр Значение по умолчанию Примечания
allowJs true Это почти никогда не нужно менять
allowUnreachableCode false
allowUnusedLabels false
checkJs false Если true вызывает проверку типов JavaScript в TypeScript
jsx "react"
jsxFactory "React.createElement"
jsxFragmentFactory "React.Fragment"
keyofStringsOnly false
lib [ "deno.window" ] Значение по умолчанию для этого параметра зависит от других настроек в Deno. Если он указан, он переопределяет значение по умолчанию. Подробнее см. ниже.
noErrorTruncation false
noFallthroughCasesInSwitch false
noImplicitAny true
noImplicitOverride true
noImplicitReturns false
noImplicitThis true
noImplicitUseStrict true
noStrictGenericChecks false
noUnusedLocals false
noUnusedParameters false
noUncheckedIndexedAccess false
reactNamespace React
strict true
strictBindCallApply true
strictFunctionTypes true
strictPropertyInitialization true
strictNullChecks true
suppressExcessPropertyErrors false
suppressImplicitAnyIndexErrors false
useUnknownInCatchVariables true

Полный список параметров компилятора и их влияния на TypeScript см. в руководстве TypeScript.

Использование свойства "lib"

Если вы работаете над проектом, который поставляет код в несколько сред выполнения, например, в браузеры, вы можете изменить типы по умолчанию, используя свойство "lib" в файле compilerOptions.

Встроенные библиотеки, которые представляют интерес для пользователей:

  • "deno.ns" - Включает все пользовательские глобальные пространства имен API Deno плюс дополнения Deno к import.meta . Как правило, это не должно создавать конфликтов с другими библиотеками или глобальными типами.
  • "deno.unstable" - Включает дополнения нестабильных API глобального пространства имен Deno.
  • "deno.window" - Это "стандартная" библиотека, используемая при проверке скриптов основного запуска Deno. Она включает "deno.ns" а также другие библиотеки типов для расширений, встроенных в Deno. Эта библиотека может конфликтовать с библиотеками, такими как "dom" и "dom.iterable", которые являются стандартными TypeScript-библиотеками.
  • "deno.worker" - Это библиотека, используемая при проверке скрипта веб-воркера Deno. Подробнее о веб-воркерах см. Type Checking Web Workers.
  • "dom.asynciterable" - В настоящее время TypeScript не включает асинхронные итераторы DOM, которые реализует Deno (плюс несколько браузеров), поэтому мы реализовали их самостоятельно до тех пор, пока они не появятся в TypeScript.

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

  • "dom" - Основная глобальная библиотека браузера, поставляемая с TypeScript. Определения типов конфликтуют во многих отношениях с "deno.window", поэтому, если используется "dom", следует рассмотреть использование только "deno.ns" для экспонирования API Deno.
  • "dom.iterable" - Расширения итераторов для глобальной библиотеки браузера.
  • "scripthost" - Библиотека для Microsoft Windows Script Host.
  • "webworker" - Основная библиотека для веб-воркеров в браузере. Как и "dom", это будет конфликтовать с "deno.window" или "deno.worker", поэтому следует рассмотреть использование только "deno.ns" для экспонирования API Deno.
  • "webworker.importscripts" - Библиотека, которая экспонирует API importScripts() в веб-воркере.
  • "webworker.iterable" - Библиотека, добавляющая итераторы к объектам внутри веб-воркера. Современные браузеры поддерживают это.

Назначение Deno и браузера

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

deno.json
{
  "compilerOptions": {
    "lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
  }
}

Это должно позволить большинству кода пройти проверку типов в Deno.

Если вы ожидаете запустить код в Deno с флагом --unstable, то вам следует добавить эту библиотеку в список:

deno.json
{
  "compilerOptions": {
    "lib": [
      "dom",
      "dom.iterable",
      "dom.asynciterable",
      "deno.ns",
      "deno.unstable"
    ]
  }
}

Как правило, при использовании опции "lib" в TypeScript, необходимо также включить библиотеку "es". В случае с "deno.ns" и "deno.unstable", они автоматически включают "esnext" при их подключении.

Примечание

Если у вас возникают ошибки типов, такие как невозможно найти document или HTMLElement, вероятно, используемая вами библиотека зависит от DOM. Это обычно встречается в пакетах, предназначенных для работы как в браузере, так и на стороне сервера. По умолчанию Deno включает только непосредственно поддерживаемые библиотеки. Предполагая, что пакет должным образом определяет среду выполнения во время выполнения, использование библиотек DOM для проверки типа кода является "безопасным".

Типы и объявления типов

Deno использует принцип разработки без поддержки нестандартной разрешения модулей. При проверке файла TypeScript сосредоточивается исключительно на его типах. В отличие от этого, компилятор tsc использует сложную логику для разрешения этих типов. По умолчанию tsc ожидает неоднозначных спецификаторов модулей с расширениями (например, .ts, .d.ts или .js). Однако Deno работает с явными спецификаторами.

Вот где становится интересно: представьте, что вы хотите использовать файл TypeScript, уже транскрибированный в JavaScript, вместе с его файлом определения типов (mod.js и mod.d.ts). Если вы импортируете mod.js в Deno, оно строго следует вашему запросу и импортирует файл JavaScript. Но вот в чём подвох: ваш код не будет так тщательно проверяться с точки зрения типов, как если бы TypeScript рассматривал файл mod.d.ts вместе с файлом mod.js.

Для решения этой проблемы Deno предлагает два решения, каждое из которых предназначено для конкретных сценариев:

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

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

Предоставление типов при импорте

Если вы используете модуль JavaScript, и у вас есть созданные типы (файл .d.ts) или вы каким-либо образом получили нужные типы, вы можете направить Deno использовать этот файл при проверке типов вместо файла JavaScript, используя подсказку компилятора @ts-types.

Например, если у вас есть модуль JavaScript, coolLib.js, и отдельный файл coolLib.d.ts, вы импортируете его так:

// @ts-types="./coolLib.d.ts"
import * as coolLib from "./coolLib.js";

При проверке типов coolLib и использовании его в вашем файле, определения типов TypeScript из coolLib.d.ts будут иметь приоритет над анализом файла JavaScript.

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

Предоставление типов при размещении

Если у вас есть доступ к исходному коду модуля или способу размещения файла на веб-сервере, есть два способа сообщить Deno о типах для определенного модуля (что не потребует никаких специальных действий от импортера).

@ts-self-types

Если вы предоставляете файл JavaScript и хотите предоставить файл объявления, содержащий типы для этого файла, вы можете указать директиву @ts-self-types в файле JS, указывая на файл объявления.

Например, если вы создаете библиотеку coolLib.js и записываете её определения типов в coolLib.d.ts, директива ts-self-types будет выглядеть так:

coolLib.js
// @ts-self-types="./coolLib.d.ts"

// ... the rest of the JavaScript ...

X-TypeScript-Types

Deno поддерживает заголовок для удаленных модулей, который указывает Deno, где найти типы для данного модуля. Например, ответ для https://example.com/coolLib.js может выглядеть примерно так:

HTTP/1.1 200 OK
Content-Type: application/javascript; charset=UTF-8
Content-Length: 648
X-TypeScript-Types: ./coolLib.d.ts

Увидев этот заголовок, Deno попытается получить https://example.com/coolLib.d.ts и использовать его при проверке типов исходного модуля.

Использование глобальных типов

В целом, лучше использовать определения типов модулей/UMD с Deno, где модуль явно импортирует типы, от которых он зависит. Модульные определения типов могут выражать расширение глобальной области через declare global в определении типа. Например:

declare global {
  var AGlobalString: string;
}

Это сделает AGlobalString доступным в глобальном пространстве имён при импорте определения типа.

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

Директива тройной косой черты

Этот вариант связывает определения типов с самим кодом. Добавив директиву тройной косой черты types в файл TS (не JS!), рядом с типом модуля, проверка типов файла включит определение типа. Например:

/// <reference types="./types.d.ts" />

Предоставленный идентификатор разрешается так же, как и любой другой идентификатор в Deno, что означает, что он требует расширения и является относительным к модулю, который его ссылается. Он также может быть полным URL-адресом:

/// <reference types="https://deno.land/x/pkg@1.0.0/types.d.ts" />

Предоставление "types" в deno.json

Ещё один вариант — предоставить значение "types" параметру "compilerOptions" в вашем файле deno.json. Например:

deno.json
{
  "compilerOptions": {
    "types": [
      "./types.d.ts",
      "https://deno.land/x/pkg@1.0.0/types.d.ts",
      "/Users/me/pkg/types.d.ts"
    ]
  }
}

Как и ссылка с тройной косой чертой выше, идентификатор, предоставленный в массиве "types", будет разрешаться как и другие идентификаторы в Deno. В случае относительных идентификаторов, он будет разрешаться относительно пути к файлу конфигурации. Убедитесь, что вы сообщаете Deno использовать этот файл, указав флаг --config=path/to/file.

Проверка типов веб-рабочих процессов

Когда Deno загружает модуль TypeScript в веб-рабочий процесс, оно автоматически проверяет тип модуля и его зависимостей по отношению к библиотеке веб-рабочих процессов Deno. Это может представлять проблему в других контекстах, таких как deno check или в редакторах. Существует несколько способов указать Deno использовать библиотеки рабочих процессов вместо стандартных библиотек Deno.

Директивы тройной косой черты

Этот вариант связывает настройки библиотеки с самим кодом. Добавив следующие директивы тройной косой черты в начале файла точки входа для скрипта рабочего процесса, Deno теперь будет проверять его как скрипт рабочего процесса Deno, независимо от того, как анализируется модуль:

/// <reference no-default-lib="true" />
/// <reference lib="deno.worker" />

Первая директива гарантирует, что не будут использоваться другие библиотеки по умолчанию. Если этого не сделать, у вас возникнут конфликтующие определения типов, потому что Deno попытается применить и стандартную библиотеку Deno. Вторая директива указывает Deno применить встроенные определения типов для Deno рабочих процессов и зависимых библиотек (например, "esnext").

Единственный недостаток заключается в том, что код становится менее переносимым на другие платформы, не использующие Deno, такие как tsc, так как только в Deno есть встроенная библиотека "deno.worker".

Предоставление "lib" настроек в deno.json

Вы можете предоставить параметр "lib" в вашем файле deno.json для указания Deno использовать файлы библиотек. Например:

deno.json
{
  "compilerOptions": {
    "target": "esnext",
    "lib": ["deno.worker"]
  }
}

Затем при выполнении подкоманды deno вам потребуется передать аргумент --config path/to/file, или, если вы используете IDE, которая использует сервер языка Deno, установите параметр deno.config.

Если у вас также есть скрипты, которые не являются рабочими процессами, вам либо нужно опустить аргумент --config, либо у вас должен быть такой, который соответствует потребностям ваших скриптов, не являющихся рабочими процессами.

Важные моменты

Семантика декларации типов

Файлы декларации типов (файлы .d.ts) следуют той же семантике, что и другие файлы в Deno. Это означает, что файлы объявления предполагаются как объявления модулей (объявления UMD), а не как глобальные объявления. Непредсказуемо, как Deno будет обрабатывать глобальные объявления.

Кроме того, если файл объявления типа импортирует что-то ещё, например, другой файл .d.ts, его разрешение следует стандартным правилам импорта Deno. Многие файлы .d.ts, которые генерируются и доступны в сети, могут несовместимы с Deno.

esm.sh — это CDN, который по умолчанию предоставляет объявления типов (через заголовок X-TypeScript-Types). Он может быть отключен путём добавления ?no-dts к URL-адресу импорта:

import React from "https://esm.sh/react?no-dts";

Поведение JavaScript при проверке типов

Когда вы импортируете код JavaScript в TypeScript в Deno, даже если вы установили checkJs в false (что является поведением по умолчанию для Deno), компилятор TypeScript всё равно проанализирует модуль JavaScript. Он пытается вывести форму экспортов из этого модуля, чтобы валидировать импорт в вашем файле TypeScript.

Обычно это не проблема при импорте стандартного ES-модуля. Однако есть случаи, когда анализ TypeScript может потерпеть неудачу, например, с модулями, имеющими специальную упаковку или являющимися глобальными модулями UMD (Universal Module Definition). В таких ситуациях лучшим подходом является предоставление какой-либо информации о типах, используя один из упомянутых ранее методов.

Внутренности

Хотя для эффективного использования TypeScript с Deno не требуется понимать внутреннее устройство Deno, это может быть полезно.

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

Для каждой зависимости используются два потенциальных «слота»: слот кода и слот типа. По мере построения графа модулей, если модуль — это то, что может быть сгенерировано в JavaScript, он заполняет слот кода, а зависимости только типов, такие как файлы .d.ts, заполняют слот типа.

Когда граф модулей построен и требуется проверка типов графа, Deno запускает компилятор TypeScript и предоставляет ему имена модулей, которые потенциально должны быть сгенерированы как JavaScript. В процессе компилятор TypeScript запросит дополнительные модули, и Deno посмотрит в слоты для зависимости, предложит слот типа, если он заполнен, прежде чем предложить слот кода.

Это означает, что когда вы импортируете модуль .d.ts, или используете одно из решений выше для предоставления альтернативных модулей типов для кода JavaScript, это то, что предоставляется TypeScript вместо этого при разрешении модуля.

© 2018–2024 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/reference/ts_config_migration

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API