vue-tsc-ci
test12026-10-2513 次阅读
为什么 tsc 不够
tsc 不认识 .vue 单文件组件,直接用 tsc 跑类型检查会跳过所有 vue 文件。vue-tsc 是 Vue 官方的类型检查器,底层复用 TypeScript,能解析 SFC 的 script、props、emits 和模板。把它放进 CI,就能在合并前拦住类型错误。
配置 tsconfig
关键点是 types 里带上 vite/client,并用 moduleResolution: Bundler 匹配 Vite 的解析规则。
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"jsx": "preserve",
"lib": ["ESNext", "DOM"],
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue", "env.d.ts"]
}
加上 vue 文件的类型声明
env.d.ts 里给 .vue 一个模块声明,否则 TS 会在 import 组件时报找不到模块。
/// <reference types="vite/client" />
declare module "*.vue" {
import type { DefineComponent } from "vue";
const component: DefineComponent<{}, {}, any>;
export default component;
}
脚本拆成 typecheck 与 build
把类型检查从构建里拆出来单独跑,CI 失败信息更聚焦,本地也能先 typecheck 再 build。
{
"scripts": {
"typecheck": "vue-tsc --noEmit",
"build": "vue-tsc --noEmit && vite build"
}
}
组件里把 props 和 emits 都标上类型
defineProps 用接口、defineEmits 用类型化调用签名,模板里就能拿到完整的类型提示与校验。
<script setup lang="ts">
interface Props {
title: string;
count?: number;
}
const props = defineProps<Props>();
const emit = defineEmits<{
(e: "increment", value: number): void;
}>();
function onClick() {
emit("increment", (props.count ?? 0) + 1);
}
</script>
<template>
<button @click="onClick">{{ title }}: {{ count ?? 0 }}</button>
</template>
CI 里跑一道
把 typecheck 放进 GitHub Actions,push 和 PR 都拦一遍,类型错误就进不了主干。
name: typecheck
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run typecheck
类型检查是花钱最少的一道质量闸门,值得每次提交都跑。
T
test1
文章作者
为什么 tsc 不够 tsc 不认识 .vue 单文件组件,直接用 tsc 跑类型检查会跳过所有 vue 文件。vue...
- 分类
- 技术
- 发布时间
- 2026-10-25
- 字数
- 约 1837 字
- 阅读
- 13 次
