コンテンツにスキップ

TypeScript

AstroにはTypeScriptのサポートが組み込まれています。Astroプロジェクト内で.ts.tsxファイルをインポートしたり、Astroコンポーネントの中に直接TypeScriptコードを書いたり、お好みでAstroの設定にastro.config.tsファイルを使ったりできます。

TypeScriptを使うと、コード内のオブジェクトやコンポーネントの形を定義することで、実行時のエラーを未然に防げます。たとえば、TypeScriptでコンポーネントのpropsに型をつけると、そのコンポーネントが受け付けないpropを設定した際にエディタ上でエラーが表示されます。

TypeScriptの恩恵を受けるために、Astroプロジェクトで必ずしもTypeScriptコードを書く必要はありません。Astroは常にコンポーネントのコードをTypeScriptとして扱い、AstroのVS Code拡張機能が可能な限り型を推論して、エディタ上で自動補完やヒント、エラー表示を提供します。

Astroの開発サーバーは型チェックをおこないませんが、コマンドラインから型エラーをチェックするための別のスクリプトを利用できます。

Astroのスタータープロジェクトには、tsconfig.jsonファイルが含まれています。TypeScriptコードを書かない場合でも、AstroやVS Codeといったツールがプロジェクトを正しく理解するために、このファイルは重要です。一部の機能(npmパッケージのインポートなど)は、tsconfig.jsonファイルがないとエディタで完全にはサポートされません。Astroを手動でインストールする場合は、このファイルを必ず自分で作成してください。

Astroには、拡張可能な3つのtsconfig.jsonテンプレート、basestrictstrictestが含まれています。baseテンプレートはモダンなJavaScript機能のサポートを有効にし、他のテンプレートのベースとしても使われます。プロジェクトでTypeScriptを書く予定がある場合は、strictまたはstrictestの使用をおすすめします。3つのテンプレートの設定は、astro/tsconfigs/で確認・比較できます。

いずれかのテンプレートを継承するには、extends設定を使います。

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

さらに、Astroの型の恩恵を受けつつ、ビルド済みファイルのチェックを避けるために、includeexcludeを次のように設定することをおすすめします。

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

公式のAstro VS Code拡張機能を使っていない場合は、Astro TypeScriptプラグインを個別にインストールできます。このプラグインはVS Code拡張機能によって自動的にインストール・設定されるため、両方をインストールする必要はありません。

このプラグインはエディタ内でのみ動作します。ターミナルでtscを実行すると、.astroファイルは完全に無視されます。代わりに、astro checkCLIコマンド (EN)を使えば、.astro.tsの両方のファイルをチェックできます。

このプラグインは、.tsファイルから.astroファイルをインポートすることもサポートしています(再エクスポートに便利です)。

Terminal window
npm install @astrojs/ts-plugin

そして、tsconfig.jsonに以下を追加します:

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

プラグインが動作していることを確認するには、.tsファイルを作成し、そこにAstroコンポーネントをインポートします。エディタから警告メッセージが表示されなければ問題ありません。

プロジェクトでUIフレームワークを使っている場合は、フレームワークに応じた追加の設定が必要になることがあります。詳しくは、各フレームワークのTypeScriptドキュメントを参照してください。(VueReactPreactSolidSvelte

可能な限り、明示的な型のインポートとエクスポートを使ってください。

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

こうすることで、Astroのバンドラーが、インポートした型をJavaScriptであるかのように誤ってバンドルしようとするエッジケースを回避できます。

tsconfig.jsonファイルで、TypeScriptに型のインポートを強制するように設定できます。verbatimModuleSyntaxtrueに設定してください。TypeScriptがインポートをチェックし、import typeを使うべき箇所を教えてくれます。この設定は、Astroのすべてのプリセットでデフォルトで有効になっています。

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

Astroは、tsconfig.jsonpaths設定で定義するインポートエイリアスをサポートしています。詳しくは、インポートガイド (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/*"]
}
}
}

カスタムの型宣言を追加するための慣習として、またはtsconfig.jsonがない場合にAstroの型の恩恵を受けるために、src/env.d.tsを作成できます。

src/env.d.ts
// カスタムの型宣言
declare var myString: string;
// Astroの型。すでに`tsconfig.json`がある場合は不要
/// <reference path="../.astro/types.d.ts" />

グローバルオブジェクトにプロパティを追加したい場合があります。これは、env.d.tsファイルにdeclareキーワードを使ってトップレベルの宣言を追加することでおこなえます。

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

これにより、window.myStringwindow.myFunctionだけでなく、globalThis.myStringglobalThis.myFunctionにも型が提供されます。

windowはクライアントサイドのコードでのみ利用できることに注意してください。globalThisはサーバーサイドとクライアントサイドの両方で利用できますが、サーバーサイドの値はクライアントと共有されません。

windowオブジェクトのプロパティにのみ型をつけたい場合は、代わりにWindowインターフェースを指定します。

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

カスタム属性やCSSプロパティの型を定義したい場合があります。.d.tsファイルでastroHTML.JSX名前空間を再宣言することで、デフォルトのJSX定義を拡張し、非標準の属性を追加できます。

src/env.d.ts
declare namespace astroHTML.JSX {
interface HTMLAttributes {
"data-count"?: number;
"data-label"?: string;
}
// styleオブジェクトに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ファイルは、アンビエントモジュールの宣言です。構文はESモジュールに似ていますが、これらのファイルではトップレベルのインポートとエクスポートが許可されていません。TypeScriptがそれらを検出すると、そのファイルはモジュール拡張(module augmentation)とみなされ、グローバル型が壊れてしまいます。

Astroは、TypeScriptによるコンポーネントのpropsの型付けをサポートしています。有効にするには、コンポーネントのフロントマターに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>
  • コンポーネントがpropsもスロットコンテンツも受け取らない場合は、type Props = Record<string, never>を使えます。
  • コンポーネントのデフォルトスロットに必ず子要素を渡す必要がある場合は、type Props = { children: any; };を使ってこれを強制できます。

追加: astro@1.6.0

Astroには、よくあるprop型のパターン向けに、いくつかの組み込みユーティリティ型が用意されています。これらはastro/typesエントリーポイントから利用できます。

Astroは、マークアップが有効なHTML属性を使っているかをチェックするためのHTMLAttributes型を提供しています。これらの型を使うと、コンポーネントのpropsを構築するのに役立ちます。

たとえば<Link>コンポーネントを作る場合、次のようにすることで、コンポーネントのpropの型に<a>タグのデフォルトのHTML属性を反映できます。

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型を直接エクスポートしていなくても参照できます。

次の例は、astro/typesComponentPropsユーティリティを使って、<Button />コンポーネントのProps型を参照する方法を示しています。

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要素としてレンダリングできるコンポーネントを簡単に構築するためのヘルパーが含まれています。これは、渡されたpropsに応じて<a>または<button>のいずれかとしてレンダリングできる<Link>のようなコンポーネントに便利です。

以下の例では、任意のHTML要素としてレンダリングできる、完全に型付けされたポリモーフィックなコンポーネントを実装しています。HTMLTag型を使って、aspropが有効な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)関数が返す型を扱うためのヘルパーが含まれています。

InferGetStaticParamsTypeAstro.params (EN)の型を、InferGetStaticPropsTypeAstro.props (EN)の型を取得できます。また、GetStaticPathsを使えば、両方を一度に推論できます。

src/pages/posts/[...id].astro
---
import type {
InferGetStaticParamsType,
InferGetStaticPropsType,
GetStaticPaths,
} from "astro";
import { getCollection } from "astro:content";
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;
// ^? { id: string; }
const { title } = Astro.props;
// ^? { draft: boolean; title: string; }
---

エディタで型エラーを確認するには、AstroのVS Code拡張機能がインストールされていることを確認してください。astro startastro buildコマンドは、esbuildでコードをトランスパイルしますが、型チェックはおこなわないことに注意してください。TypeScriptエラーが含まれている場合にコードのビルドを防ぐには、package.jsonの「build」スクリプトを次のように変更します:

package.json
{
"scripts": {
"build": "astro build",
"build": "astro check && astro build",
},
}
Astroにおける.tsファイルのインポート (EN)について、さらに詳しく学べます。
TypeScriptの設定について、さらに詳しく学べます。

複数のJSXフレームワークを同時に型付けする際のエラー

Section titled “複数のJSXフレームワークを同時に型付けする際のエラー”

同じプロジェクトで複数のJSXフレームワークを使うと、各フレームワークがtsconfig.json内で異なる、ときには競合する設定を必要とするため、問題が発生することがあります。

解決策: もっともよく使うフレームワークに応じて、jsxImportSource設定react(デフォルト)、preact、またはsolid-jsに設定します。そして、その設定と競合する別のフレームワークのファイル内でプラグマコメントを使います。

jsxImportSource: reactというデフォルト設定の場合は、次のように記述します。

// Preactの場合
/** @jsxImportSource preact */
// Solidの場合
/** @jsxImportSource solid-js */
貢献する コミュニティ スポンサー