diff --git a/src/content/docs/ja/basics/layouts.mdx b/src/content/docs/ja/basics/layouts.mdx index b397a6e46e631..feca5964ad8c0 100644 --- a/src/content/docs/ja/basics/layouts.mdx +++ b/src/content/docs/ja/basics/layouts.mdx @@ -147,7 +147,7 @@ const { frontmatter } = Astro.props; ``` -`MarkdownLayoutProps`を使用して、レイアウトの[`Props`型](/ja/guides/typescript/#component-props)を設定できます。 +`MarkdownLayoutProps`を使用して、レイアウトの[`Props`型](/ja/guides/typescript/#コンポーネントのprops)を設定できます。 ```astro title="src/layouts/BlogPostLayout.astro" ins={2,4-9} --- diff --git a/src/content/docs/ja/guides/integrations-guide/alpinejs.mdx b/src/content/docs/ja/guides/integrations-guide/alpinejs.mdx index c4baf37e6dc7b..9698a4db7a980 100644 --- a/src/content/docs/ja/guides/integrations-guide/alpinejs.mdx +++ b/src/content/docs/ja/guides/integrations-guide/alpinejs.mdx @@ -155,7 +155,7 @@ export default (Alpine: Alpine) => { ## TypeScriptのインテリセンス -`@astrojs/alpine`インテグレーションは、[グローバルウィンドウオブジェクト](/ja/guides/typescript/#window-and-globalthis)に`Alpine`を追加します。IDEのオートコンプリートのために、`src/env.d.ts`に以下を追加します。 +`@astrojs/alpine`インテグレーションは、[グローバルウィンドウオブジェクト](/ja/guides/typescript/#windowとglobalthis)に`Alpine`を追加します。IDEのオートコンプリートのために、`src/env.d.ts`に以下を追加します。 ```ts title="src/env.d.ts" interface Window { diff --git a/src/content/docs/ja/guides/integrations-guide/netlify.mdx b/src/content/docs/ja/guides/integrations-guide/netlify.mdx index 47152f053d135..7b8acaff8e852 100644 --- a/src/content/docs/ja/guides/integrations-guide/netlify.mdx +++ b/src/content/docs/ja/guides/integrations-guide/netlify.mdx @@ -134,7 +134,7 @@ const {

{city}から来たフレンドリーな訪問者さん、こんにちは!

``` -TypeScriptを使用している場合は、`src/env.d.ts`を更新して`NetlifyLocals`を使用することで、[適切な型指定を取得](/ja/guides/typescript/#extending-global-types)できます。 +TypeScriptを使用している場合は、`src/env.d.ts`を更新して`NetlifyLocals`を使用することで、[適切な型指定を取得](/ja/guides/typescript/#グローバル型の拡張)できます。 ```ts title="src/env.d.ts" type NetlifyLocals = import('@astrojs/netlify').NetlifyLocals diff --git a/src/content/docs/ja/guides/integrations-guide/vercel.mdx b/src/content/docs/ja/guides/integrations-guide/vercel.mdx index b90c0285c25f0..d38ea9e77fd0c 100644 --- a/src/content/docs/ja/guides/integrations-guide/vercel.mdx +++ b/src/content/docs/ja/guides/integrations-guide/vercel.mdx @@ -462,7 +462,7 @@ export default defineConfig({ }); ``` -エッジミドルウェアは、`ctx.locals.vercel.edge`としてVercelの[`RequestContext`](https://vercel.com/docs/functions/edge-middleware/middleware-api#requestcontext)にアクセスできます。TypeScriptを使用している場合は、`src/env.d.ts`を更新して`EdgeLocals`を使用することで、[適切な型指定を取得](/ja/guides/typescript/#extending-global-types)できます。 +エッジミドルウェアは、`ctx.locals.vercel.edge`としてVercelの[`RequestContext`](https://vercel.com/docs/functions/edge-middleware/middleware-api#requestcontext)にアクセスできます。TypeScriptを使用している場合は、`src/env.d.ts`を更新して`EdgeLocals`を使用することで、[適切な型指定を取得](/ja/guides/typescript/#グローバル型の拡張)できます。 ```ts type EdgeLocals = import('@astrojs/vercel').EdgeLocals diff --git a/src/content/docs/ja/guides/migrate-to-astro/from-create-react-app.mdx b/src/content/docs/ja/guides/migrate-to-astro/from-create-react-app.mdx index bb39e1bb9672f..42aea1b21b0a5 100644 --- a/src/content/docs/ja/guides/migrate-to-astro/from-create-react-app.mdx +++ b/src/content/docs/ja/guides/migrate-to-astro/from-create-react-app.mdx @@ -270,7 +270,7 @@ Astroは静的HTMLを出力するため、ビルド後のファイルを使っ ### CRAのインポートをAstroに変換 -[ファイルインポート](/ja/guides/imports/)を必ず正しい相対パスで記述します。[インポートエイリアス](/ja/guides/typescript/#import-aliases)を使うか、フルパスを書くかのいずれかです。 +[ファイルインポート](/ja/guides/imports/)を必ず正しい相対パスで記述します。[インポートエイリアス](/ja/guides/typescript/#インポートエイリアス)を使うか、フルパスを書くかのいずれかです。 `.astro`を含む一部のファイル型は**拡張子を省略できません**。拡張子まで明示してインポートしてください。 diff --git a/src/content/docs/ja/guides/sessions.mdx b/src/content/docs/ja/guides/sessions.mdx index f61d27574b5f0..dbc809c368fa0 100644 --- a/src/content/docs/ja/guides/sessions.mdx +++ b/src/content/docs/ja/guides/sessions.mdx @@ -194,7 +194,7 @@ export const onRequest = defineMiddleware(async (context, next) => { デフォルトではセッションデータには型がなく、任意のキーに任意のデータを保存できます。値は[devalue](https://github.com/Rich-Harris/devalue)を使用してシリアライズ・デシリアライズされます。これはコンテンツコレクションやアクションで使用されているのと同じライブラリです。そのため、サポートされる型も同じで、文字列、数値、`Date`、`Map`、`Set`、`URL`、配列、プレーンなオブジェクトが含まれます。 -`src/env.d.ts`ファイルを作成し、`App.SessionData`型の宣言を追加することで、セッションデータの[TypeScript型を定義](/ja/guides/typescript/#extending-global-types)することもできます。 +`src/env.d.ts`ファイルを作成し、`App.SessionData`型の宣言を追加することで、セッションデータの[TypeScript型を定義](/ja/guides/typescript/#グローバル型の拡張)することもできます。 ```ts title="src/env.d.ts" declare namespace App { diff --git a/src/content/docs/ja/guides/syntax-highlighting.mdx b/src/content/docs/ja/guides/syntax-highlighting.mdx index 358d82192ba8d..2bc6f0a498f76 100644 --- a/src/content/docs/ja/guides/syntax-highlighting.mdx +++ b/src/content/docs/ja/guides/syntax-highlighting.mdx @@ -124,7 +124,7 @@ Astroで使用する場合は次に注意します。 - [``](#code-)(Shikiベース) - [``](#prism-)(Prismベース) -各コンポーネントの`Props`は[`ComponentProps`型](/ja/guides/typescript/#componentprops-type)で参照できます。 +各コンポーネントの`Props`は[`ComponentProps`型](/ja/guides/typescript/#componentprops型)で参照できます。 ### `` diff --git a/src/content/docs/ja/guides/typescript.mdx b/src/content/docs/ja/guides/typescript.mdx new file mode 100644 index 0000000000000..4431d8939a36c --- /dev/null +++ b/src/content/docs/ja/guides/typescript.mdx @@ -0,0 +1,378 @@ +--- +title: TypeScript +description: Astro組み込みのTypeScriptサポートの使い方を学びます。 +i18nReady: true +--- +import Since from '~/components/Since.astro' +import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro' + +Astroには[TypeScript](https://www.typescriptlang.org/)のサポートが組み込まれています。Astroプロジェクト内で`.ts`や`.tsx`ファイルをインポートしたり、[Astroコンポーネント](/ja/basics/astro-components/#コンポーネントスクリプト)の中に直接TypeScriptコードを書いたり、お好みでAstroの設定に[`astro.config.ts`](/ja/guides/configuring-astro/#astroの設定ファイル)ファイルを使ったりできます。 + +TypeScriptを使うと、コード内のオブジェクトやコンポーネントの形を定義することで、実行時のエラーを未然に防げます。たとえば、TypeScriptで[コンポーネントのpropsに型をつける](#コンポーネントのprops)と、そのコンポーネントが受け付けないpropを設定した際にエディタ上でエラーが表示されます。 + +TypeScriptの恩恵を受けるために、Astroプロジェクトで必ずしもTypeScriptコードを書く必要はありません。Astroは常にコンポーネントのコードをTypeScriptとして扱い、[AstroのVS Code拡張機能](/ja/editor-setup/)が可能な限り型を推論して、エディタ上で自動補完やヒント、エラー表示を提供します。 + +Astroの開発サーバーは型チェックをおこないませんが、コマンドラインから型エラーをチェックするための[別のスクリプト](#型チェック)を利用できます。 + +## セットアップ + +Astroのスタータープロジェクトには、`tsconfig.json`ファイルが含まれています。TypeScriptコードを書かない場合でも、AstroやVS Codeといったツールがプロジェクトを正しく理解するために、このファイルは重要です。一部の機能(npmパッケージのインポートなど)は、`tsconfig.json`ファイルがないとエディタで完全にはサポートされません。Astroを手動でインストールする場合は、このファイルを必ず自分で作成してください。 + +### TSConfigのテンプレート + +Astroには、拡張可能な3つの`tsconfig.json`テンプレート、`base`、`strict`、`strictest`が含まれています。`base`テンプレートはモダンなJavaScript機能のサポートを有効にし、他のテンプレートのベースとしても使われます。プロジェクトでTypeScriptを書く予定がある場合は、`strict`または`strictest`の使用をおすすめします。3つのテンプレートの設定は、[astro/tsconfigs/](https://github.com/withastro/astro/blob/main/packages/astro/tsconfigs/)で確認・比較できます。 + +いずれかのテンプレートを継承するには、[`extends`設定](https://www.typescriptlang.org/tsconfig#extends)を使います。 + +```json title="tsconfig.json" +{ + "extends": "astro/tsconfigs/base" +} +``` + +さらに、Astroの型の恩恵を受けつつ、ビルド済みファイルのチェックを避けるために、`include`と`exclude`を次のように設定することをおすすめします。 + +```json title="tsconfig.json" ins={3-4} +{ + "extends": "astro/tsconfigs/base", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] +} +``` + +### TypeScriptエディタプラグイン + +[公式のAstro VS Code拡張機能](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode)を使っていない場合は、[Astro TypeScriptプラグイン](https://www.npmjs.com/package/@astrojs/ts-plugin)を個別にインストールできます。このプラグインはVS Code拡張機能によって自動的にインストール・設定されるため、両方をインストールする必要はありません。 + +このプラグインはエディタ内でのみ動作します。ターミナルで`tsc`を実行すると、`.astro`ファイルは完全に無視されます。代わりに、[`astro check`CLIコマンド](/ja/reference/cli-reference/#astro-check)を使えば、`.astro`と`.ts`の両方のファイルをチェックできます。 + +このプラグインは、`.ts`ファイルから`.astro`ファイルをインポートすることもサポートしています(再エクスポートに便利です)。 + + + + ```shell + npm install @astrojs/ts-plugin + ``` + + + ```shell + pnpm add @astrojs/ts-plugin + ``` + + + ```shell + yarn add @astrojs/ts-plugin + ``` + + + +そして、`tsconfig.json`に以下を追加します: + +```json title="tsconfig.json" +{ + "compilerOptions": { + "plugins": [ + { + "name": "@astrojs/ts-plugin" + }, + ], + } +} +``` +プラグインが動作していることを確認するには、`.ts`ファイルを作成し、そこにAstroコンポーネントをインポートします。エディタから警告メッセージが表示されなければ問題ありません。 + +### UIフレームワーク + +プロジェクトで[UIフレームワーク](/ja/guides/framework-components/)を使っている場合は、フレームワークに応じた追加の設定が必要になることがあります。詳しくは、各フレームワークのTypeScriptドキュメントを参照してください。([Vue](https://vuejs.org/guide/typescript/overview.html#using-vue-with-typescript)、[React](https://react-typescript-cheatsheet.netlify.app/docs/basic/setup)、[Preact](https://preactjs.com/guide/v10/typescript)、[Solid](https://www.solidjs.com/guides/typescript)、[Svelte](https://svelte.dev/docs/svelte/typescript)) + +## 型のインポート + +可能な限り、明示的な型のインポートとエクスポートを使ってください。 + +```js del={1} ins={2} ins="type" +import { SomeType } from "./script"; +import type { SomeType } from "./script"; +``` + +こうすることで、Astroのバンドラーが、インポートした型をJavaScriptであるかのように誤ってバンドルしようとするエッジケースを回避できます。 + +`tsconfig.json`ファイルで、TypeScriptに型のインポートを強制するように設定できます。[`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax)を`true`に設定してください。TypeScriptがインポートをチェックし、`import type`を使うべき箇所を教えてくれます。この設定は、Astroのすべてのプリセットでデフォルトで有効になっています。 + +```json title="tsconfig.json" ins={3} +{ + "compilerOptions": { + "verbatimModuleSyntax": true + } +} +``` + +## インポートエイリアス + +Astroは、`tsconfig.json`の`paths`設定で定義するインポートエイリアスをサポートしています。詳しくは、[インポートガイド](/ja/guides/imports/#aliases)を参照してください。 + +```astro title="src/pages/about/nate.astro" "@components" "@layouts" +--- +import HelloWorld from "@components/HelloWorld.astro"; +import Layout from "@layouts/Layout.astro"; +--- +``` + +```json title="tsconfig.json" {4-5} +{ + "compilerOptions": { + "paths": { + "@components/*": ["./src/components/*"], + "@layouts/*": ["./src/layouts/*"] + } + } +} +``` + +## グローバル型の拡張 + +カスタムの型宣言を追加するための慣習として、または`tsconfig.json`がない場合にAstroの型の恩恵を受けるために、`src/env.d.ts`を作成できます。 + +```ts title="src/env.d.ts" +// カスタムの型宣言 +declare var myString: string; + +// Astroの型。すでに`tsconfig.json`がある場合は不要 +/// +``` + +### `window`と`globalThis` + +グローバルオブジェクトにプロパティを追加したい場合があります。これは、`env.d.ts`ファイルに`declare`キーワードを使ってトップレベルの宣言を追加することでおこなえます。 + +```ts title="src/env.d.ts" +declare var myString: string; +declare function myFunction(): boolean; +``` + +これにより、`window.myString`と`window.myFunction`だけでなく、`globalThis.myString`と`globalThis.myFunction`にも型が提供されます。 + +`window`はクライアントサイドのコードでのみ利用できることに注意してください。`globalThis`はサーバーサイドとクライアントサイドの両方で利用できますが、サーバーサイドの値はクライアントと共有されません。 + +`window`オブジェクトのプロパティにのみ型をつけたい場合は、代わりに`Window`インターフェースを指定します。 + +```ts title="src/env.d.ts" +interface Window { + myFunction(): boolean; +} +``` + +### 非標準の属性を追加する + +カスタム属性やCSSプロパティの型を定義したい場合があります。`.d.ts`ファイルで`astroHTML.JSX`名前空間を再宣言することで、デフォルトのJSX定義を拡張し、非標準の属性を追加できます。 + +```ts title="src/env.d.ts" +declare namespace astroHTML.JSX { + interface HTMLAttributes { + "data-count"?: number; + "data-label"?: string; + } + + // styleオブジェクトにCSSカスタムプロパティを追加する + interface CSSProperties { + "--theme-color"?: "black" | "white"; + } +} +``` + +:::note +`astroHTML`は、`.astro`コンポーネント内にグローバルに注入されます。TypeScriptファイルで使うには、[トリプルスラッシュディレクティブ](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html)を使います。 + +```ts +/// + +type MyAttributes = astroHTML.JSX.ImgHTMLAttributes; +``` +::: + +### インポートを使う + +プロジェクト内の他の場所や外部ライブラリで宣言された型を再利用して、グローバル型を拡張したい場合があります。これには、[動的インポート](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import)を使います。 + +```ts title="src/env.d.ts" +type Product = { + id: string; + name: string; + price: number; +}; + +declare namespace App { + interface Locals { + orders: Map + session: import("./lib/server/session").Session | null; + user: import("my-external-library").User; + } +} +``` + +`.d.ts`ファイルは、[アンビエントモジュール](https://www.typescriptlang.org/docs/handbook/modules/reference.html#ambient-modules)の宣言です。構文はESモジュールに似ていますが、これらのファイルではトップレベルのインポートとエクスポートが許可されていません。TypeScriptがそれらを検出すると、そのファイルは[モジュール拡張(module augmentation)](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation)とみなされ、グローバル型が壊れてしまいます。 + +## コンポーネントのprops + +Astroは、TypeScriptによるコンポーネントのpropsの型付けをサポートしています。有効にするには、コンポーネントのフロントマターにTypeScriptの`Props`インターフェースを追加します。`export`文を使ってもかまいませんが、必須ではありません。[AstroのVS Code拡張機能](/ja/editor-setup/)は自動的に`Props`インターフェースを探し、そのコンポーネントを別のテンプレート内で使う際に適切なTSサポートを提供します。 + +```astro title="src/components/HelloProps.astro" ins={2-5} +--- +interface Props { + name: string; + greeting?: string; +} + +const { greeting = "Hello", name } = Astro.props; +--- +

{greeting}, {name}!

+``` + +### よくあるprop型のパターン + +- コンポーネントがpropsもスロットコンテンツも受け取らない場合は、`type Props = Record`を使えます。 +- コンポーネントのデフォルトスロットに必ず子要素を渡す必要がある場合は、`type Props = { children: any; };`を使ってこれを強制できます。 + +## 型ユーティリティ + +

+ +Astroには、よくあるprop型のパターン向けに、いくつかの組み込みユーティリティ型が用意されています。これらは`astro/types`エントリーポイントから利用できます。 + +### 組み込みのHTML属性 + +Astroは、マークアップが有効なHTML属性を使っているかをチェックするための`HTMLAttributes`型を提供しています。これらの型を使うと、コンポーネントのpropsを構築するのに役立ちます。 + +たとえば``コンポーネントを作る場合、次のようにすることで、コンポーネントのpropの型に``タグのデフォルトのHTML属性を反映できます。 + +```astro title="src/components/Link.astro" ins="HTMLAttributes" ins="HTMLAttributes<'a'>" +--- +import type { HTMLAttributes } from "astro/types"; + +// `type`を使う +type Props = HTMLAttributes<"a">; + +// または`interface`で拡張する +interface Props extends HTMLAttributes<"a"> { + myProp?: boolean; +} + +const { href, ...attrs } = Astro.props; +--- + + + +``` + +### `ComponentProps`型 + +

+ +このエクスポートされた型を使うと、別のコンポーネントが受け取る`Props`を、そのコンポーネントが`Props`型を直接エクスポートしていなくても参照できます。 + +次の例は、`astro/types`の`ComponentProps`ユーティリティを使って、`