title | description | i18nReady |
---|---|---|
TypeScript |
Astro組み込みのTypeScriptサポートの使い方を学ぶ。 |
true |
import Since from '/components/Since.astro'
import PackageManagerTabs from '/components/tabs/PackageManagerTabs.astro'
AstroにはTypeScriptのサポートが組み込まれています。Astroプロジェクトで.ts
や.tsx
ファイルをインポートしたり、Astroコンポーネントの中で直接TypeScriptコードを書いたり、お好みでastro.config.ts
ファイルを使うこともできます。
TypeScriptにより、オブジェクトやコンポーネントの形状(shape)をコードで定義して実行時エラーを防ぐことができます。たとえば、TypeScriptでコンポーネントのpropsに型を付けると、コンポーネントが受け付けないpropを設定した場合にエディタ内にエラーが発生します。
AstroプロジェクトでTypeScriptコードを書かなくても、その恩恵を受けられます。Astroは常にコンポーネントのコードをTypeScriptとして扱い、Astro VSCode拡張機能は自動補完やヒント、エラーをエディタ内で提供するためにできる限りの推論を行います。
Astroの開発サーバーは型チェックを行いませんが、スクリプトの追加によりコマンドラインから型エラーをチェックできます。
Astroのスタータープロジェクトにはtsconfig.json
ファイルが含まれています。TypeScriptコードを書かない場合でも、AstroやVS Codeなどのツールがプロジェクトを理解するために、このファイルは重要です。tsconfig.json
ファイルがないと、npmパッケージのインポートなどの一部の機能がエディタで完全にサポートされません。Astroを手動でインストールする場合は、必ずこのファイルを自分で作成してください。
Astroには、base
、strict
、strictest
という3つの拡張可能なtsconfig.json
のテンプレートが含まれています。base
テンプレートは、JavaScriptのモダンな機能のサポートを可能とし、他のテンプレートの基礎としても使用されます。プロジェクトでTypeScriptを書く予定がある場合は、strict
またはstrictest
を使用することをお勧めします。astro/tsconfigs/で3つのテンプレートの設定を確認・比較できます。
いずれかのテンプレートを継承するには、extends
という設定項目を使用します。
{
"extends": "astro/tsconfigs/base"
}
また、Viteのクライアント型をプロジェクトで利用できるように、テンプレートにはsrc
フォルダ内にenv.d.ts
が含まれています。
/// <reference types="astro/client" />
VSCodeを使っていない場合は、Astro TypeScriptプラグインをインストールすることで、.ts
ファイルからの.astro
ファイルのインポートをサポートできます(これは再エクスポートに便利なことがあります)。
そして、以下の設定をtsconfig.json
に追加します。
"compilerOptions": {
"plugins": [
{
"name": "@astrojs/ts-plugin"
},
],
}
プラグインが正しく機能していることを確認するには、.ts
ファイルを作成し、その中にAstroコンポーネントをインポートします。エディタには警告メッセージが何も表示されないはずです。
プロジェクトでUIフレームワークを使用する場合は、フレームワークに応じた追加の設定が必要かもしれません。詳細については、フレームワークのTypeScriptドキュメントを参照してください。 (Vue、React、Preact、Solid)
可能な限り、明示的な型のインポートとエクスポートを使用しましょう。
import { SomeType } from './script';
import type { SomeType } from './script';
こうすることで、Astroのバンドラーがインポートした型をJavaScriptであるかのように誤ってバンドルするようなエッジケースを避けることができます。
tsconfig.json
ファイルで、型のインポートを強制するようにTypeScriptを設定できます。verbatimModuleSyntax
をtrue
に設定してください。TypeScriptはインポートをチェックし、いつimport type
を使用するべきかを伝えてくれます。この設定はAstroのすべてのプリセットでデフォルトで有効化されています。
{
"compilerOptions": {
"verbatimModuleSyntax": true
}
}
Astroは、tsconfig.json
とjsconfig.json
のpaths
設定で定義するimportエイリアスをサポートしています。
---
import HelloWorld from '@components/HelloWorld.astro';
import Layout from '@layouts/Layout.astro';
---
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"]
}
}
}
グローバルオブジェクトにプロパティを追加することもできます。これは、env.d.ts
ファイルにdeclare
キーワードを使用してトップレベルの宣言を追加することで可能です。
declare const myString: string;
declare function myFunction(): boolean;
これにより、globalThis.myString
とglobalThis.myFunction
、さらにwindow.myString
とwindow.myFunction
に型が提供されます。
window
はクライアントサイドのコード内でのみ利用可能なことに注意してください。globalThis
はサーバーサイドとクライアントサイドの両方で利用できますが、サーバーサイドの値はクライアントとは共有されません。
window
オブジェクト上のプロパティにのみ型付けしたい場合は、代わりにWindow
インターフェイスを提供してください。
interface Window {
myFunction(): boolean;
}
AstroはTypeScriptによるコンポーネントpropsの型付けをサポートしています。有効にするには、コンポーネントのfrontmatterにTypeScriptのProps
インターフェースを追加します。export
文を使用することもできますが、必須ではありません。Astro VSCode拡張機能は、Props
インターフェースを自動的に探し、そのコンポーネントを他のテンプレート内で使用するときに適切なTSサポートを提供します。
---
interface Props {
name: string;
greeting?: string;
}
const { greeting = 'Hello', name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>
-
コンポーネントがpropsやスロット経由のコンテンツを受け取らない場合は、
type Props = Record<string, unknown>
を使用できます。 -
コンポーネントがデフォルトスロットから子要素を受け取る必要がある場合は、
type Props = { children: any; };
によりこれを強制できます。
Astroには、propsに型を付ける際によく出くわすパターン向けに、組み込みのユーティリティ型を提供しています。これらはastro/types
エントリポイントから利用可能です。
Astroは、マークアップが有効なHTML属性を使用していることを確認するためにHTMLAttributes
型を提供しています。この型により、コンポーネントのpropsを構成しやすくなります。
たとえば<Link>
コンポーネントを作成する場合、次のようにコンポーネントのprops型に<a>
タグのデフォルトHTML属性を反映できます。
---
import { 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>
また、.d.ts
ファイルでastroHTML.JSX
名前空間を再宣言し、デフォルトのJSX定義を拡張して非標準の属性を追加することも可能です。
// src/custom-attributes.d.ts
declare namespace astroHTML.JSX {
interface HTMLAttributes {
'data-count'?: number;
'data-label'?: string;
}
// CSSのカスタムプロパティをスタイルオブジェクトに追加する
interface CSSProperties {
'--theme-color'?: 'black' | 'white';
}
}
:::note
astroHTML
は.astro
コンポーネント内にグローバルに注入されます。TypeScriptファイルで使用するには、triple-slashディレクティブを使用します。
/// <reference types="astro/astro-jsx" />
type MyAttributes = astroHTML.JSX.ImgHTMLAttributes;
:::
この型エクスポートを利用すると、別のコンポーネントがProps
型を直接エクスポートしていなかったとしても、そのコンポーネントが受け付けるProps
を参照できるようになります。
以下に示すのは、astro/types
のComponentProps
を使用して<Button />
コンポーネントのProps
型を参照する例です。
---
import type { ComponentProps } from 'astro/types';
import Button from "./Button.astro";
type ButtonProps = ComponentProps<typeof Button>;
---
Astroには、異なるHTML要素としてレンダリング可能なコンポーネントを、完全に型安全に作成することを簡単にするヘルパーがあります。これは、渡されたpropsに応じて、<a>
または<button>
のいずれかとしてレンダリングされる<Link>
のようなコンポーネントに便利です。
以下の例では、完全に型付けされた、任意のHTML要素としてレンダリングできるポリモーフィックなコンポーネントを実装しています。HTMLTag
型を使うことで、as
propが有効な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には、動的ルーティングに対してgetStaticPaths()
関数から返される型を扱うためのヘルパーがあります。
Astro.params
の型はInferGetStaticParamsType
で、Astro.props
の型はInferGetStaticPropsType
で取得できます。
---
import type { InferGetStaticParamsType, InferGetStaticPropsType, GetStaticPaths } from 'astro';
export const getStaticPaths = (async () => {
const posts = await getCollection('blog');
return posts.map((post) => {
return {
params: { slug: post.slug },
props: { draft: post.data.draft, title: post.data.title },
};
});
}) satisfies GetStaticPaths;
type Params = InferGetStaticParamsType<typeof getStaticPaths>;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
const { slug } = Astro.params as Params;
// ^? { slug: string; }
const { title } = Astro.props;
// ^? { draft: boolean; title: string; }
---
エディタで型エラーを確認するには、Astro VS Code拡張機能をインストールしてください。astro start
とastro build
コマンドは、esbuildでコードをトランスパイルしますが、型チェックは実行しないことに注意してください。TypeScriptのエラーが含まれている場合にビルドされないようにするには、package.json
のbuildスクリプトを次のように変更します。
"scripts": {
"build": "astro build",
"build": "astro check && astro build",
},
:::note
astro check
は、TypeScriptプロジェクトに含まれるすべてのファイルをチェックします。SvelteとVueファイル内の型をチェックするには、それぞれsvelte-check
とvue-tsc
パッケージを使用できます。
:::
import ReadMore from '~/components/ReadMore.astro'
Astroにおける.ts
ファイルのインポートについてもっと読む。
TypeScriptの設定についてもっと読む。
同じプロジェクトで複数のJSXフレームワークを使用する場合、フレームワークごとにtsconfig.json
内の設定が異なり、互いにコンフリクトして問題が発生することがあります。
解決策:最も使用するフレームワークに合わせて、jsxImportSource
設定をreact
(デフォルト)、preact
またはsolid-js
に設定します。次に、競合する異なるフレームワークのファイル内でプラグマコメントを使用します。
デフォルト設定であるjsxImportSource: react
の場合は、次のように使用します。
// Preact向け
/** @jsxImportSource preact */
// Solid向け
/** @jsxImportSource solid-js */