使用Nuxt+TS+Composition API开发Link组件是否需结合TS类型与prop验证器
二者结合是非常有实际价值的,属于「静态校验提前抓错+运行时校验兜底」的典型最佳实践,完全不是冗余操作
先说两者的能力边界差异:
- TS 类型校验仅在开发/编译阶段生效,打包上线后就完全失去约束能力,只能覆盖纯静态编码的场景,以下场景它完全无法校验:
- 你的 Link 组件要提供给 JS 项目、或者未开启 TS 严格校验的项目使用
- target 的值是动态来源:比如从后端接口返回、从URL参数读取、从本地存储获取,这些值只有运行时才能确定,TS 根本没有能力提前校验
- 组件作为公共包发布后,使用者可以通过类型断言、any 类型等方式绕开 TS 校验
- Vue 提供的 prop 自定义 validator 是运行时校验,刚好可以补全以上所有静态校验覆盖不到的场景,只要运行时传入的值不符合规则,开发环境就会在控制台抛出明确警告,你也可以在校验不通过时主动上报异常、或者 fallback 到默认值,避免非法属性导致页面跳转逻辑异常等线上问题。
你当前的代码可以做小优化减少冗余
你现在的允许值列表在类型定义和 validator 里写了两次,后续要修改允许值需要改两处,建议抽成公共常量,只维护一份即可:
import { defineComponent } from '@nuxtjs/composition-api'; // 抽成常量,仅维护一次 const ALLOWED_TARGETS = ['_self', '_blank', '_parent', '_top'] as const; type TargetType = typeof ALLOWED_TARGETS[number]; export default defineComponent({ name: 'Link', props: { target: { type: String as () => TargetType, default: '_self', validator: (value: string): value is TargetType => { return ALLOWED_TARGETS.includes(value as TargetType); }, }, }, });
适用场景补充
如果你的组件只是自己业务项目里自用、所有传值都是静态写死的、全团队都开启了TS严格校验,你可以酌情考虑要不要省掉运行时校验;但如果是公共组件、或者涉及动态传值的场景,非常建议保留二者结合的写法,线上出问题的排查成本远高于多写几行校验代码的成本。
内容的提问来源于stack exchange,提问作者Théo Lavaux
相关产品推荐
相关产品推荐

