mcpField
P
principle-type-system-discipline

principle-type-system-discipline

github.com/mdsmithaustin开发8179 次安装今天更新
代码仓库

关于 principle-type-system-discipline

面向开发者的跨语言类型系统技能,旨在让编译器拒绝不可能状态、混用的基本类型和未处理的变体,并强调构造式建模、边界解析及穷尽检查。

主要功能

  1. 01让非法状态无法表示
  2. 02从有效值构造类型
  3. 03为语义基本类型添加品牌
  4. 04在边界解析无类型数据
  5. 05要求穷尽匹配
  6. 06从权威 Schema 派生类型

适用场景

  1. 01设计不含矛盾字段的变体
  2. 02区分含义不同的 ID
  3. 03验证进入应用的数据
  4. 04确保新增变体触发编译期处理

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mdsmithaustin/pstack --skill principle-type-system-discipline

安装后在 Claude Code 中输入/principle-type-system-discipline确认已加载。

附带文件agents/openai.yaml

详细介绍

类型系统纪律

让编译器拒绝不可能的状态、不匹配的基本类型和未处理的变体。与其不断增加处理程序,不如优先从定义上消除错误和特殊情况。TypeScript 语法请参阅 typescript-best-practices 技能。

  • 让非法状态无法表示。 将变体建模为和类型(判别联合、带载荷的枚举、密封类),而不是用一堆可选字段表示矛盾的组合,让它们也能通过编译。{ completed: boolean; completedAt?: Date } 允许出现 completed: true 但没有日期的情况。可以从 completedAt 推导布尔值,或建模为 { kind: 'open' } | { kind: 'done'; at: Date }。如果你需要写注释说明字段组合在什么情况下才有效,就应将其拆分为和类型。
  • 类型是构造方式,而非限制条件。 从你想要的值出发构建类型,而不是通过检查从较宽泛的类型中排除不符合条件的值。非空列表由一个头部元素和其余元素组成。有效的时间范围由开始时间和时长组成。选择一种无法构造非法值的形状,并在此基础上向调用方提供所需接口。
  • 为具有语义的基本类型添加品牌。 UserId 和 OrderId 底层都是字符串,但不应混用。为每个类型指定独立类型,例如在 TypeScript 中使用品牌交叉类型,或在其他语言中使用 newtype。创建时验证一次,后续就信任该类型。如果两个参数使用相同的基本类型却表示不同含义,就为它们添加品牌。
  • 外部数据在解析前没有类型。 RPC 载荷、JSON、IPC 消息、CLI 参数、配置文件、环境变量、数据库行。应在每个边界设置解析函数,将非结构化输入转换为类型化模型。principle-boundary-discipline 技能说明了验证应放在哪里。
  • 不要欺骗类型系统。 类型转换、不安全强制转换,以及绕过编译器的断言函数,都是潜在的运行时崩溃。如果编译器无法证明某个事实,就证明它(验证、缩小范围、细化模型),否则就承认类型转换是一种风险。追踪每个 any、as 或 assertNotNull,直到其所在边界,并在那里验证。
  • 穷尽匹配是编译器的工作。 对和类型的匹配必须在新增变体却未处理时编译失败,这样编译器就能告诉下一个 Agent 应在哪里添加分支。使用你所用语言的惯用方式:TypeScript 中使用类型为 never 的绑定,Rust 中使用未注释的 match,Haskell 中使用 -Wincomplete-patterns,Kotlin 中使用密封类匹配穷尽性检查。
  • 根据权威模式派生类型。 如果 Protocol Buffer、OpenAPI 规范、GraphQL 模式、数据库迁移、设计令牌文件或其他文件定义了某种结构,就从中派生类型,而不是手动编写一套并行类型。使用 Skill 工具调用 principle-encode-lessons-in-structure。
  • 只在存在部分性时增强类型。 运行时断言、空值检查或“这不应该发生”的抛错,都表明类型过于宽泛。将该检查上移到类型中,然后就此为止。类型系统的职责是追踪每个使用位置必须处理的情况,而不是尽可能精确地描述数据。优先使用全函数。空列表的 sum 为 0,因此它接受普通列表。空列表的 head 没有答案,因此它要求非空列表。如果不做任何修改也不会发生崩溃,就保留普通类型。

评论

支持 Markdown