TypeScript
Astro 内置了对 TypeScript 的支持。你可以在 Astro 项目中导入 .ts
和 .tsx
文件,在 Astro 组件中直接编写 TypeScript 代码,甚至可以使用 astro.config.ts
文件来配置 Astro。
使用 TypeScript,你可以通过在代码中定义对象和组件的形态来防止运行时错误。例如,如果你使用 TypeScript 为组件的 props 添加类型,当你设置一个组件不接受的 prop 时,你的编辑器就会报错。
你无需在 Astro 项目中编写 TypeScript 代码也能从中受益。Astro 始终将你的组件代码视为 TypeScript,并且 Astro VS Code 扩展会尽可能地推断类型,以便在你的编辑器中提供自动补全、提示和错误。
Astro 开发服务器不会执行任何类型检查,但你可以使用单独的脚本从命令行检查类型错误。
Astro 入门项目在你的项目中包含一个 tsconfig.json
文件。即使你不编写 TypeScript 代码,这个文件也很重要,这样像 Astro 和 VS Code 这样的工具才能知道如何理解你的项目。如果没有 tsconfig.json
文件,某些功能(如 npm 包导入)在编辑器中将无法得到完全支持。如果你是手动安装 Astro,请务必自己创建此文件。
TSConfig 模板
标题为“TSConfig 模板”的部分Astro 中包含了三个可扩展的 tsconfig.json
模板:base
、strict
和 strictest
。base
模板启用了对现代 JavaScript 功能的支持,并作为其他模板的基础。如果你计划在项目中使用 TypeScript,我们建议使用 strict
或 strictest
。你可以在 astro/tsconfigs/ 查看和比较这三个模板的配置。
要继承其中一个模板,请使用 extends
设置
{ "extends": "astro/tsconfigs/base"}
此外,我们建议按如下方式设置 include
和 exclude
,以利用 Astro 类型并避免检查已构建的文件
{ "extends": "astro/tsconfigs/base", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"]}
你可以创建一个 src/env.d.ts
文件,这是一种约定俗成的做法,用于添加自定义类型声明,或者在没有 tsconfig.json
文件的情况下利用 Astro 的类型。
// Custom types declarationsdeclare var myString: string;
// Astro types, not necessary if you already have a `tsconfig.json`/// <reference path="../.astro/types.d.ts" />
TypeScript 编辑器插件
标题为“TypeScript 编辑器插件”的部分如果你没有使用官方的 Astro VS Code 扩展,可以单独安装 Astro TypeScript 插件。该插件由 VS Code 扩展自动安装和配置,你无需同时安装两者。
此插件仅在编辑器中运行。在终端中运行 tsc
时,.astro
文件会被完全忽略。你可以改用 astro check
CLI 命令来检查 .astro
和 .ts
文件。
此插件还支持从 .ts
文件导入 .astro
文件(这对于重新导出很有用)。
npm install @astrojs/ts-plugin
pnpm add @astrojs/ts-plugin
yarn add @astrojs/ts-plugin
然后,将以下内容添加到你的 tsconfig.json
中
{ "compilerOptions": { "plugins": [ { "name": "@astrojs/ts-plugin" }, ], }}
要检查插件是否正常工作,请创建一个 .ts
文件并在其中导入一个 Astro 组件。你的编辑器中不应该出现任何警告信息。
UI 框架
标题为“UI 框架”的部分如果你的项目使用了 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
时通知你。此设置在我们的所有预设中默认启用。
{ "compilerOptions": { "verbatimModuleSyntax": true }}
导入别名
标题为“导入别名”的部分Astro 支持你在 tsconfig.json
的 paths
配置中定义的导入别名。阅读我们的指南以了解更多信息。
---import HelloWorld from "@components/HelloWorld.astro";import Layout from "@layouts/Layout.astro";---
{ "compilerOptions": { "paths": { "@components/*": ["src/components/*"], "@layouts/*": ["src/layouts/*"] } }}
扩展 window
和 globalThis
标题为“扩展 window 和 globalThis”的部分你可能想要向全局对象添加一个属性。你可以通过在你的 env.d.ts
文件中使用 declare
关键字添加顶级声明来实现
declare var 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 VS Code 扩展将自动查找 Props
接口,并为你提供正确的 TS 支持。
---interface Props { name: string; greeting?: string;}
const { greeting = "Hello", name } = Astro.props;---<h2>{greeting}, {name}!</h2>
常见的 Prop 类型模式
标题为“常见的 Prop 类型模式”的部分- 如果你的组件不接受任何 props 或插槽内容,你可以使用
type Props = Record<string, never>
。 - 如果你的组件必须将子元素传递给其默认插槽,你可以通过使用
type Props = { children: any; };
来强制执行此操作。
类型工具
标题为“类型工具”的部分
添加于: astro@1.6.0
Astro 自带了一些用于常见 prop 类型模式的内置工具类型。这些类型可以在 astro/types
入口下找到。
内置 HTML 属性
标题为“内置 HTML 属性”的部分Astro 提供了 HTMLAttributes
类型来检查你的标记是否使用了有效的 HTML 属性。你可以使用这些类型来帮助构建组件 props。
例如,如果你正在构建一个 <Link>
组件,你可以执行以下操作,以在组件的 prop 类型中镜像 <a>
标签的默认 HTML 属性。
---import type { HTMLAttributes } from "astro/types";
// use a `type`type Props = HTMLAttributes<"a">;
// or extend with an `interface`interface Props extends HTMLAttributes<"a"> { myProp?: boolean;}
const { href, ...attrs } = Astro.props;---<a href={href} {...attrs}> <slot /></a>
也可以通过在 .d.ts
文件中重新声明 astroHTML.JSX
命名空间来扩展默认的 JSX 定义,以添加非标准属性。
declare namespace astroHTML.JSX { interface HTMLAttributes { "data-count"?: number; "data-label"?: string; }
// Add a CSS custom property to the style object interface CSSProperties { "--theme-color"?: "black" | "white"; }}
astroHTML
在 .astro
组件内部是全局注入的。要在 TypeScript 文件中使用它,请使用三斜线指令
/// <reference types="astro/astro-jsx" />
type MyAttributes = astroHTML.JSX.ImgHTMLAttributes;
ComponentProps
类型
标题为“ComponentProps 类型”的部分
添加于: astro@4.3.0
即使另一个组件没有直接导出其 Props
类型,此类型导出也允许你引用该组件接受的 Props
。
下面的示例展示了如何使用来自 astro/types
的 ComponentProps
工具来引用 <Button />
组件的 Props
类型
---import type { ComponentProps } from "astro/types";import Button from "./Button.astro";
type ButtonProps = ComponentProps<typeof Button>;---
多态类型
标题为“多态类型”的部分
添加于: astro@2.5.0
Astro 包含一个辅助函数,可以更轻松地构建能够以不同 HTML 元素呈现并具有完全类型安全的组件。这对于像 <Link>
这样的组件很有用,它可以根据传递给它的 props 渲染为 <a>
或 <button>
。
下面的示例实现了一个完全类型化的多态组件,可以渲染为任何 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} />
推断 getStaticPaths()
类型
标题为“推断 getStaticPaths() 类型”的部分
添加于: astro@2.1.0
Astro 包含一些辅助函数,用于处理动态路由的 getStaticPaths()
函数返回的类型。
你可以使用 InferGetStaticParamsType
获取 Astro.params
的类型,使用 InferGetStaticPropsType
获取 Astro.props
的类型,或者你可以使用 GetStaticPaths
来一次性推断两者
---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 错误时进行构建,请将 package.json
中的“build”脚本更改为以下内容
{ "scripts": { "build": "astro build", "build": "astro check && astro build", },}
astro check
会检查 TypeScript 项目中包含的所有文件。要检查 Svelte 和 Vue 文件中的类型,你可以分别使用 svelte-check
和 vue-tsc
包。
.ts
文件导入 的更多信息。
故障排除
标题为“故障排除”的部分为多个 JSX 框架设置类型时的错误
标题为“为多个 JSX 框架设置类型时的错误”的部分在同一项目中使用多个 JSX 框架时可能会出现问题,因为每个框架在 tsconfig.json
中需要不同且有时会相互冲突的设置。
解决方案:根据你最常使用的框架,将 jsxImportSource
设置为 react
(默认)、preact
或 solid-js
。然后,在来自不同框架的任何冲突文件中使用编译指示注释。
对于 jsxImportSource: react
的默认设置,你可以使用
// For Preact/** @jsxImportSource preact */
// For Solid/** @jsxImportSource solid-js */