首页 / Astro 教程 / TypeScript 支持

Astro 教程

TypeScript 支持

本教程共 56 篇 · 第 43 篇 · 更新于 2026-08-07 · 约 10 分钟阅读

AstroAstro 教程TypeScripttsconfigastro checkProps类型

本节目标:了解 Astro 内建的 TypeScript 支持,tsconfig 模板、astro check 类型检查、组件 Props 类型与工具类型分别怎么用。

Astro 内建支持 TypeScript(微软推出的 JavaScript 超集,给代码加类型标注)。好处是:你提前标注”这个对象长什么样、这个组件能收哪些属性”,编辑器就能在写错时立刻提醒,把很多运行时错误挡在写代码阶段。本章讲 Astro 里 TypeScript 的常用姿势。

不用写 TS 也能受益

先放宽心:你写 TypeScript,也照样能享受它的好处。Astro 始终把你的组件脚本当成 TypeScript 来处理;装上官方的 Astro VS Code 扩展后,它会尽可能推断类型,给你自动补全、提示和报错。所以哪怕全程写普通 JavaScript,体验也会比裸写强。

不过开发服务器不会做类型检查(它用 esbuild 只转译)。要命令行查类型,得用 astro check(第 42 章)。

tsconfig 模板

每个 Astro 起步项目都带一个 tsconfig.json。即使你不写 TS,这个文件也很重要——它让 VS Code、Astro 理解你的项目(比如有些 npm 包导入没它就不识别)。Astro 内置三套可继承的模板:

  • base:支持现代 JavaScript 特性,也是另两套的基础。
  • strict:更严格的类型检查。
  • strictest:最严格。

打算写 TS,推荐从 strictstrictest 起步。继承方式用 extends

{
  "extends": "astro/tsconfigs/base"
}

建议再加上 includeexclude,既能用到 Astro 类型、又跳过构建产物:

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

TypeScript 编辑器插件

如果你没用官方 VS Code 扩展,可以单独装 @astrojs/ts-plugin,让编辑器支持 .astro 文件的类型。VS Code 扩展已经自动配好它,两者不用都装。这个插件只在编辑器里跑;在终端跑 tsc 时会忽略 .astro 文件——此时用 astro check 来检查 .astro.ts

UI 框架的额外设置

项目里用了 React / Vue / Svelte 等框架组件时,可能要在 tsconfig.json 里加对应框架的 TypeScript 设置。具体看各框架自己的文档。

显式类型导入

尽量用 import type 显式导入类型:

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

这样能避免打包器误把”类型”当”代码”打包。可以在 tsconfig.json 里设 verbatimModuleSyntax: true(Astro 预设默认开启),让 TypeScript 强制你用 import type

导入别名

tsconfig.jsonpaths 里配导入别名(import alias,给长路径起个短名字),写 import 就更清爽:

{
  "compilerOptions": {
    "paths": {
      "@components/*": ["./src/components/*"],
      "@layouts/*": ["./src/layouts/*"]
    }
  }
}

之后就能写 import HelloWorld from "@components/HelloWorld.astro",不用数 ../

扩展全局类型

约定上用 src/env.d.ts 放自定义类型声明,或补充 Astro 类型。例如给全局对象加属性:

// src/env.d.ts
declare var myString: string;

interface Window {
  myFunction(): boolean;
}

想给自定义 HTML 属性或 CSS 变量加类型,可重声明 astroHTML.JSX 命名空间:

declare namespace astroHTML.JSX {
  interface HTMLAttributes {
    "data-count"?: number;
  }
  interface CSSProperties {
    "--theme-color"?: "black" | "white";
  }
}
Note

.d.ts 是环境声明文件,语法像模块但不能有顶层 import/export,否则会变成”模块增强”而破坏全局类型。

组件 Props 类型

给组件属性加类型,是 TS 在 Astro 里最常见的用法。在组件 frontmatter 里写个 Props 接口即可:

---
// src/components/HelloProps.astro
interface Props {
  name: string;
  greeting?: string;
}

const { greeting = "Hello", name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>

VS Code 扩展会自动找这个 Props 接口,你在该组件被使用时就有类型提示。两个常见模式:无属性用 type Props = Record<string, never>;必须有插槽内容用 type Props = { children: any }

内置工具类型

Astro 在 astro/types 下提供几个顺手的类型工具:

  • HTMLAttributes:检查你用的 HTML 属性是否合法。比如做 <Link> 组件时复用 <a> 的属性类型:
---
import type { HTMLAttributes } from "astro/types";
type Props = HTMLAttributes<"a">;
const { href, ...attrs } = Astro.props;
---
<a href={href} {...attrs}><slot /></a>
  • ComponentProps(v4.3+):引用别的组件收的 Props 类型,哪怕它没导出:
import type { ComponentProps } from "astro/types";
import Button from "./Button.astro";
type ButtonProps = ComponentProps<typeof Button>;
  • Polymorphic(v2.5+):做一个能渲染成不同 HTML 标签、还带完整类型的组件(如既能是 <a> 又能是 <button><Link>)。

  • 推断 getStaticPaths 类型InferGetStaticParamsTypeInferGetStaticPropsTypeGetStaticPath(动态路由第 15 章用得上),帮你拿到 Astro.paramsAstro.props 的精确类型。

类型检查怎么接进构建

想让”有类型错误就构建失败”,把 build 脚本改成先 checkbuild

{
  "scripts": {
    "build": "astro check && astro build"
  }
}

多个 JSX 框架冲突

同一项目用多个 JSX 框架(React + Preact + Solid)时,tsconfig.json 的 JSX 设置会打架。解法:把 jsxImportSource 设成你最常用的那个(默认 react),在”不同框架”的文件顶部加 pragma 注释:

// 给 Preact 文件加:
/** @jsxImportSource preact */
// 给 Solid 文件加:
/** @jsxImportSource solid-js */

strict 与 strictest 差在哪

base 只开现代 JS 特性;strict 开启 TypeScript 的标准严格检查;stricteststrict 基础上再加更严的规则(比如禁止隐式 any、要求显式返回值等)。新手从 strict 起步压力适中;团队项目追求质量可用 strictest

类型从哪来:astro/client

Astro 自动生成 .astro/types.d.ts,里面有 astro:* 系列虚拟模块的类型、内容集合类型等。它就是 astro sync 的产物,也是编辑器能识别 astro:contentastro:actions 的原因。一般你不用手动碰它,知道”类型自动生成”即可。

一个 Props 类型的实用例子

除了基础属性,配合 HTMLAttributes 复用原生标签类型很常见。比如做卡片组件:

---
import type { HTMLAttributes } from "astro/types";
type Props = HTMLAttributes<"div"> & { variant?: "default" | "highlight" };
const { variant = "default", ...attrs } = Astro.props;
---
<div class={variant} {...attrs}><slot /></div>

这样卡片既能收自定义 variant,又能收普通 <div> 的所有属性(如 idclassstyle)。

astro check 和 tsc 的区别

终端里跑 tsc 会忽略 .astro 文件(它不认识这种格式);而 astro check 专门能查 .astro.ts。所以检查 Astro 项目请用 astro check,别用裸 tsc。编辑器里的报错则来自 TS 插件(或 VS Code 扩展),和 astro check 是两套互补的检查,一个写代码时提示、一个命令行里把关。

类型报错怎么读

类型报错看起来吓人,但套路固定:先看”哪个文件哪一行”,再看”期望的类型”和”你给的类型”哪里不一致。比如 Props 标了 name: string,你用组件时没传 name,就会报”缺少属性 name”。从具体属性名入手,比通读整段报错高效。

让 .astro 文件被 TS 识别

.astro 不是标准文件类型,要让 tsc、打包器和编辑器正确识别它,靠的就是 astro sync 生成的 .astro/types.d.ts(里面声明了 *.astro 模块)。所以如果你在 .ts 文件里 import 一个 .astro 组件却报”找不到模块”,先跑一次 astro sync(或 astro dev 会自动跑)。这也是为什么前面说”sync 产物是类型基础”。

给全局状态加类型:App.Locals

中间件(第 37 章)里常往 context.locals 塞用户信息等数据,方便后续页面读取。你可以在 env.d.ts 里给 App.Locals 加类型,这样读写 locals 都有提示:

declare namespace App {
  interface Locals {
    user: import("my-lib").User | null;
  }
}

这种”扩展全局类型”的方式,让你在不改 Astro 源码的前提下,把自定义数据接进框架的类型系统。类似的还有给 astro:env、内容集合加类型,思路一致:都在 env.d.tsastro/types 上做声明合并。

小结

Astro 内建 TypeScript:组件脚本就是 TS,装 VS Code 扩展即可享受推断。类型检查靠 astro check,可接进 build 脚本。tsconfig.jsonastro/tsconfigs 模板继承;组件 Props 用 Props 接口标注;astro/types 下还有 HTMLAttributes、ComponentProps 等工具类型。多 JSX 框架冲突用 jsxImportSource + pragma 解决。

下一章我们看开发工具栏:写代码时有哪些现成的调试帮手。