统一属性检查规范的核心是建立可复用、可配置、可验证的机制,而非堆砌判断语句;需分层设计校验边界与时机,结合 typescript 与运行时校验双保险,集中管理逻辑并纳入 ci/测试流程。

统一属性检查规范,关键不是写更多判断语句,而是把“什么时候该检查”“检查什么”“怎么报错”变成可复用、可配置、可验证的机制。
明确属性检查的边界和时机
属性检查不该出现在每个函数开头堆砌 typeof 或 in 判断。应分层设计:
- 数据输入入口(如 API 响应解析、表单提交、props 传入)必须做严格校验
- 内部逻辑中对已知结构的数据(如组件 state、模块内部对象)不做重复检查,靠类型定义或初始化约束保障
- 异步回调或第三方库返回值属于“不可信数据”,需显式校验后再使用
用 TypeScript + 运行时校验双保险
TypeScript 提供编译期类型提示,但无法拦截运行时错误。推荐组合使用:
- 接口定义用 interface/type 声明形状(shape),例如:
interface User { id: number; name: string; email?: string } - 关键路径添加轻量级运行时校验,比如用 zod 或 io-ts 定义 schema 并 parse:
const userSchema = z.object({ id: z.number(), name: z.string() }); const result = userSchema.safeParse(data); // 返回 { success: boolean, data? }这样既保留开发体验,又守住生产环境底线。
集中管理校验逻辑,避免散落各处
不要在组件里写 if (!obj || !obj.id),而是封装成可复用的工具:
- 创建
validateRequiredKeys(obj, keys: string[])统一处理必填字段缺失 - 对常见结构(如分页响应、树形数据)提供预设校验器,例如
isValidTreeData(data) - 所有校验失败统一抛出带语义的错误,如
new ValidationError('User missing required field: name'),便于监控和调试
把校验规则纳入 CI 和测试流程
- 在单元测试中覆盖典型非法输入场景,验证校验器是否触发预期行为
- 使用 ESLint 插件(如 eslint-plugin-no-unsafe-nested-access)拦截常见属性访问风险,例如
obj?.a?.b?.c未校验就直接调用方法 - Git 提交前通过 lint-staged 自动检查新增代码中是否遗漏关键校验点(可通过自定义规则识别
data.id类访问而无前置校验)
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











