Vue 3 的 <script setup lang="ts"> 通过 defineProps<T> 泛型实现编译时严格类型校验,配合 strict: true 的 tsconfig 配置与 Volar 插件,确保 props 类型安全、可推导、易维护;运行时 validator 仅作兜底补充。

Vue 3 的 <script setup lang="ts"> 结合 TypeScript 实现组件属性的严格校验,核心在于利用 defineProps 的类型系统与编译时检查能力,而非运行时手动验证。TypeScript 在开发阶段就能捕获类型错误,配合 Vue 的响应式机制,让 props 安全、可推导、易维护。
用泛型方式定义 props 类型(推荐)
这是最简洁、类型最完整的方式,支持自动推导模板中 props 的类型、IDE 智能提示、以及编译期报错。
- 声明一个接口或类型别名描述 props 结构
- 将该类型作为
defineProps<T>()的泛型参数传入 - 无需额外配置,TypeScript 即可校验父组件传值是否符合要求
示例:
<script setup lang="ts">import { defineProps } from 'vue'
interface Props {
title: string
count?: number
status: 'active' | 'inactive'
onConfirm: (id: string) => void
}
const props = defineProps<Props>()
</script>
此时若父组件写 <MyComp title={123} />,TS 编译器会立刻报错:Type 'number' is not assignable to type 'string'。
立即学习“前端免费学习笔记(深入)”;
用运行时校验补充类型边界(按需启用)
TypeScript 类型只在开发/编译阶段生效,无法拦截生产环境的非法 props(如 JS 动态赋值、v-bind 对象解构等)。若需运行时防护,可在 defineProps 中混合使用类型声明 + 运行时 validator:
- validator 函数接收实际传入值,返回布尔值或抛出错误
- 它不替代类型系统,而是兜底——比如校验字符串长度、URL 格式、枚举值合法性等 TS 难以表达的约束
- 注意:validator 仅在非生产环境(
process.env.NODE_ENV !== 'production')下执行
示例:
const props = defineProps({email: {
type: String,
required: true,
validator: (v: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)
}
})
确保 tsconfig.json 启用严格模式
没有严格的 TypeScript 配置,类型校验就形同虚设。必须确认项目根目录的 tsconfig.json 包含以下关键项:
-
"strict": true—— 启用所有严格检查(含noImplicitAny、strictNullChecks等) -
"moduleResolution": "node"—— 正确解析模块路径,尤其影响defineProps的类型推导 -
"skipLibCheck": false(建议关闭)—— 确保 Vue 类型声明也被严格校验 - 若使用 Volar(非 Vetur),还需确认其已启用 “Take Over Mode”,否则 TS 插件可能无法识别
defineProps宏
避免常见陷阱
几个容易导致类型失效的典型问题:
- 不要在
defineProps外部用any或as any强转 props 对象——这会绕过全部校验 - 不要用对象解构直接提取 props(如
const { title } = props)后又重新赋值——解构后的变量失去响应性且类型可能弱化;应始终通过props.xxx访问 - 若 props 中有可选属性,访问前需判空或使用可选链(
props?.title),否则 TS 会报错 - 组合式 API 中,
defineProps必须顶层调用,不能包裹在函数或条件语句中,否则 Volar/TS 无法识别


















