Перейти к содержимому

TypeScript

Astro поставляется со встроенной поддержкой TypeScript. Вы можете импортировать файлы .ts и .tsx в свой проект Astro, писать код на TypeScript прямо внутри компонента Astro и даже использовать файл astro.config.ts для конфигурации Astro, если хотите.

Используя TypeScript, вы можете предотвращать ошибки во время выполнения, задавая в коде структуру объектов и компонентов. Например, если вы используете TypeScript, чтобы типизировать пропсы вашего компонента, вы получите ошибку в редакторе, если зададите пропс, который ваш компонент не принимает.

Вам не нужно писать код на TypeScript в своих проектах Astro, чтобы извлекать из него пользу. Astro всегда рассматривает код вашего компонента как TypeScript, а расширение Astro для VS Code будет выводить столько сведений, сколько сможет, чтобы предоставить автодополнение, подсказки и ошибки в редакторе.

Сервер разработки Astro не выполняет проверку типов, но вы можете использовать отдельный скрипт, чтобы проверять ошибки типов из командной строки.

Стартовые проекты Astro включают файл tsconfig.json в ваш проект. Даже если вы не пишете код на TypeScript, этот файл важен, чтобы такие инструменты, как Astro и VS Code, понимали ваш проект. Некоторые возможности (например, импорт npm-пакетов) не полностью поддерживаются в редакторе без файла tsconfig.json. Если вы устанавливаете Astro вручную, обязательно создайте этот файл самостоятельно.

В Astro включены три расширяемых шаблона tsconfig.json: base, strict и strictest. Шаблон base включает поддержку современных возможностей JavaScript и также служит основой для остальных шаблонов. Мы рекомендуем использовать strict или strictest, если вы планируете писать на TypeScript в своём проекте. Вы можете просмотреть и сравнить три конфигурации шаблонов в astro/tsconfigs/.

Чтобы наследоваться от одного из шаблонов, используйте настройку extends:

tsconfig.json
{
"extends": "astro/tsconfigs/base"
}

Дополнительно мы рекомендуем задать include и exclude следующим образом, чтобы пользоваться типами Astro и не проверять скомпилированные файлы:

tsconfig.json
{
"extends": "astro/tsconfigs/base",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}

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

Этот плагин работает только в редакторе. При запуске tsc в терминале файлы .astro полностью игнорируются. Вместо этого вы можете использовать CLI команду astro check (EN), чтобы проверять и файлы .astro, и файлы .ts.

Этот плагин также поддерживает импорт файлов .astro из файлов .ts (это может быть полезно для повторного экспорта).

Terminal window
npm install @astrojs/ts-plugin

Затем добавьте следующее в ваш tsconfig.json:

tsconfig.json
{
"compilerOptions": {
"plugins": [
{
"name": "@astrojs/ts-plugin"
},
],
}
}

Чтобы проверить, что плагин работает, создайте файл .ts и импортируйте в него компонент Astro. В вашем редакторе не должно быть предупреждений.

Если ваш проект использует UI-фреймворк (EN), могут потребоваться дополнительные настройки в зависимости от фреймворка. Подробности см. в документации TypeScript для вашего фреймворка. (Vue, React, Preact, Solid, Svelte)

По возможности используйте явные импорты и экспорты типов.

import { SomeType } from "./script";
import type { SomeType } from "./script";

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

Вы можете настроить TypeScript так, чтобы он принудительно требовал импорты типов в файле tsconfig.json. Установите verbatimModuleSyntax в true. TypeScript будет проверять ваши импорты и подсказывать, когда следует использовать import type. Эта настройка включена по умолчанию во всех наших пресетах.

tsconfig.json
{
"compilerOptions": {
"verbatimModuleSyntax": true
}
}

Astro поддерживает алиасы импортов, которые вы задаёте в конфигурации paths в tsconfig.json. Подробнее см. в нашем руководстве по импортам (EN).

src/pages/about/nate.astro
---
import HelloWorld from "@components/HelloWorld.astro";
import Layout from "@layouts/Layout.astro";
---
tsconfig.json
{
"compilerOptions": {
"paths": {
"@components/*": ["./src/components/*"],
"@layouts/*": ["./src/layouts/*"]
}
}
}

Вы можете создать src/env.d.ts как соглашение для добавления собственных объявлений типов или, чтобы воспользоваться типами Astro, если у вас нет tsconfig.json:

src/env.d.ts
// Собственные объявления типов
declare var myString: string;
// Типы Astro не нужны, если у вас уже есть `tsconfig.json`
/// <reference path="../.astro/types.d.ts" />

Иногда может понадобиться добавить свойство в глобальный объект. Это можно сделать, добавив верхнеуровневые объявления с ключевым словом declare в файл env.d.ts:

src/env.d.ts
declare var myString: string;
declare function myFunction(): boolean;

Это добавит типизацию для globalThis.myString и globalThis.myFunction, а также для window.myString и window.myFunction.

Обратите внимание, что window доступен только в клиентском коде. globalThis доступен и на сервере, и на клиенте, однако его серверное значение не будет передано клиенту.

Если вы хотите типизировать только свойство объекта window, задайте вместо этого интерфейс Window:

src/env.d.ts
interface Window {
myFunction(): boolean;
}

Иногда может понадобиться определить тип для пользовательских атрибутов или CSS-свойств. Вы можете расширить стандартные JSX-определения, чтобы добавить нестандартные атрибуты, переопределив пространство имён astroHTML.JSX в файле .d.ts.

src/env.d.ts
declare namespace astroHTML.JSX {
interface HTMLAttributes {
"data-count"?: number;
"data-label"?: string;
}
// Добавьте пользовательское CSS-свойство в объект стиля
interface CSSProperties {
"--theme-color"?: "black" | "white";
}
}

Иногда может понадобиться расширить глобальные типы, используя типы, объявленные в другом месте вашего проекта или во внешней библиотеке. Для этого используйте динамические импорты:

src/env.d.ts
type Product = {
id: string;
name: string;
price: number;
};
declare namespace App {
interface Locals {
orders: Map<string, Product[]>
session: import("./lib/server/session").Session | null;
user: import("my-external-library").User;
}
}

Файл .d.ts — это объявление ambient module. Хотя его синтаксис похож на ES-модули, такие файлы не допускают верхнеуровневые импорты/экспорты. Если TypeScript встретит что-то подобное, файл будет считаться module augmentation, и это сломает ваши глобальные типы.

Astro поддерживает типизацию пропсов компонентов с помощью TypeScript. Чтобы включить это, добавьте интерфейс TypeScript Props в метаданные вашего компонента. Оператор export можно использовать, но это не обязательно. Расширение Astro для VS Code автоматически будет искать интерфейс Props и обеспечит корректную поддержку TS, когда вы используете этот компонент внутри другого шаблона.

src/components/HelloProps.astro
---
interface Props {
name: string;
greeting?: string;
}
const { greeting = "Hello", name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>
  • Если ваш компонент не принимает пропсов или содержимого слота, можно использовать type Props = Record<string, never>.
  • Если в компонент обязательно нужно передать дочернее содержимое в слот по умолчанию, это можно задать с помощью type Props = { children: any; };.

Добавлено в: astro@1.6.0

Astro поставляется с несколькими встроенными вспомогательными типами для распространённых шаблонов типизации пропсов. Они доступны из astro/types.

Astro предоставляет тип HTMLAttributes, чтобы проверить, что в вашей разметке используются допустимые HTML-атрибуты. Эти типы можно использовать, чтобы помочь в построении пропсов компонентов.

Например, если вы создаёте компонент <Link>, можно сделать следующее, чтобы повторить стандартные HTML-атрибуты для тегов <a> в типах пропсов вашего компонента.

src/components/Link.astro
---
import type { HTMLAttributes } from "astro/types";
// используйте `type`
type Props = HTMLAttributes<"a">;
// или расширьте с помощью `interface`
interface Props extends HTMLAttributes<"a"> {
myProp?: boolean;
}
const { href, ...attrs } = Astro.props;
---
<a href={href} {...attrs}>
<slot />
</a>

Добавлено в: astro@4.3.0

Этот экспорт типа позволяет ссылаться на Props, которые принимает другой компонент, даже если этот компонент не экспортирует тип Props напрямую.

В следующем примере показано использование утилиты ComponentProps из astro/types для ссылки на типы Props компонента <Button />:

src/pages/index.astro
---
import type { ComponentProps } from "astro/types";
import Button from "./Button.astro";
type ButtonProps = ComponentProps<typeof Button>;
---

Добавлено в: astro@2.5.0

Astro включает вспомогательный инструмент, который упрощает создание компонентов, способных рендериться как разные HTML-элементы при полной безопасности типов. Это полезно для компонентов вроде <Link>, которые могут рендериться либо как <a>, либо как <button> в зависимости от переданных пропсов.

Пример ниже реализует полностью типизированный полиморфный компонент, который может рендериться как любой HTML-элемент. Тип HTMLTag используется, чтобы гарантировать, что проп as содержит допустимый HTML-элемент.

---
import type { HTMLTag, Polymorphic } from "astro/types";
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }>;
const { as: Tag, ...props } = Astro.props;
---
<Tag {...props} />

Добавлено в: astro@2.1.0

Astro включает вспомогательные типы для работы с типами, возвращаемыми вашей функцией getStaticPaths() (EN) для динамических маршрутов.

Вы можете получить тип Astro.params (EN) с помощью InferGetStaticParamsType, а тип Astro.props (EN) с помощью InferGetStaticPropsType; либо можно использовать GetStaticPaths, чтобы получить оба сразу:

src/pages/posts/[...id].astro
---
import type {
InferGetStaticParamsType,
InferGetStaticPropsType,
GetStaticPaths,
} from "astro";
export const getStaticPaths = (async () => {
const posts = await getCollection("blog");
return posts.map((post) => {
return {
params: { id: post.id },
props: { draft: post.data.draft, title: post.data.title },
};
});
}) satisfies GetStaticPaths;
type Params = InferGetStaticParamsType<typeof getStaticPaths>;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
const { id } = Astro.params as Params;
// ^? { id: string; }
const { title } = Astro.props;
// ^? { draft: boolean; title: string; }
---

Чтобы видеть ошибки типов в редакторе, убедитесь, что у вас установлено расширение Astro для VS Code. Обратите внимание, что команды astro start и astro build транспилируют код с помощью esbuild, но не выполняют проверку типов. Чтобы сборка не проходила, если в коде есть ошибки TypeScript, измените скрипт “build” в package.json на следующий:

package.json
{
"scripts": {
"build": "astro build",
"build": "astro check && astro build",
},
}
Подробнее о импортах файлов .ts (EN) в Astro.
Подробнее о конфигурации TypeScript.

Ошибки типизации нескольких JSX-фреймворков одновременно

Заголовок раздела «Ошибки типизации нескольких JSX-фреймворков одновременно»

При использовании нескольких JSX-фреймворков в одном проекте может возникнуть проблема, поскольку каждому фреймворку нужны разные, а иногда и конфликтующие настройки внутри tsconfig.json.

Решение: установите значение jsxImportSource в react (по умолчанию), preact или solid-js в зависимости от наиболее часто используемого фреймворка. Затем используйте pragma comment внутри любого конфликтующего файла из другого фреймворка.

При значении по умолчанию jsxImportSource: react следует использовать:

// Для Preact
/** @jsxImportSource preact */
// Для Solid
/** @jsxImportSource solid-js */
Внести свой вклад Сообщество Поддержать