用途:这是一套把不变量从运行时检查迁移到类型系统的 TypeScript 类型安全手册,包含六种可组合技术,用于让非法状态不可表示,在编译期而非测试期捕获缺陷。它不是通用 TypeScript 风格指南,适用于领域模型设计、SDK/库公开 API、互斥形状的可辨识联合、实体 ID 建模(任务 ID、用户 ID 等)以及边界加固(输入校验、数据库读取、外部 API 响应)。不适用于应用胶水代码(路由处理器、UI 组件)、脚本、迁移、一次性工具,或运行时检查更清晰且同样安全的代码。
核心立场:让非法状态不可表示;在信任边界做运行时校验,其余位置用类型约束,即“解析而非校验”;删除 as 强制转换是证据而非风险,生产代码中的每个 as 都应视为审计目标。
六种技术:1) 品牌化 ID,用于结构上都是 string 但语义不同的实体 ID;2) ?: never 互斥,用于无需字面量标签字段的可辨识联合;3) NoInfer<T>,用于消费位置参数,防止后置参数拓宽推断类型;4) 负向类型测试,用 @ts-expect-error 把架构不变量锁进测试套件;5) 哨兵常量,用于必须通过 schema 校验的魔法字符串;6) 强制转换清理,审计 as 表达式,区分信任边界转换与隐藏类型漏洞的生产转换。
使用方式:入口命令包括 /type-safety audit(读取目标文件或包,枚举 as 表达式与 ID 类型用法,输出按优先级排序的修复清单,不修改代码)、/type-safety design(设计新类型前加载手册)、/type-safety <technique>(跳转到特定技术参考,如 branded-ids、mutual-exclusion)、/type-safety <file-path>(审计指定文件)、/type-safety(无参数时加载概览)。审计流程为:确定范围、枚举强制转换、枚举 ID 类型、枚举可辨识联合、分类、排优先级、输出 markdown 报告,审计期间不修改代码。
限制与反模式:不要给每个字符串都加品牌;已有字面量判别时不要再用 ?: never;NoInfer 不用于返回类型;负向类型测试需锚定具体错误注释;生产代码禁止 as unknown as T;只对需要 schema 校验的魔法字符串使用哨兵;小型应用中使用品牌化 ID 属于过度设计。各技术的详细模式、示例与反模式见对应参考文件(branded-ids.md、discriminated-unions.md、generic-positions.md、negative-type-tests.md、cast-cleanup.md)。