解析,而非校验 —— 在一门拒绝你的编程语言中
Parse, Don't Validate – In a Language That Doesn't Want You To

原始链接: https://cekrem.github.io/posts/parse-dont-validate-typescript/

在 TypeScript 中,开发者往往倾向于进行“验证”(即通过 `if` 语句检查数据),而非“解析”(即将原始数据转换为精确且类型安全的数据格式)。虽然验证能确认数据是否正确,但类型系统会立即“忘记”这一结论,从而导致重复检查和“散弹式解析”。 为了解决这一问题,作者提倡“解析,而非验证”这一原则,即让类型系统成为事实的唯一来源。通过使用“标称类型”(branded types,用于防止类型混淆)和“可辨识联合”(discriminated unions,用于显式处理错误),你可以确保只有通过解析器的数据才能被视为有效的领域对象。 尽管 TypeScript 缺乏像 Elm 或 F# 那样对该模式的原生支持,但你可以通过以下方式实现: 1. 将外部输入视为 `unknown`。 2. 创建返回 `Parsed` 类型的“智能构造函数”。 3. 使用 Zod 等库来自动化这些边界检查。 归根结底,其目标是停止依赖记忆来跟踪数据完整性。相反,应将验证结果编码进类型本身,使非法状态无法被表示,从而确保代码的真正安全。

抱歉。
相关文章

原文

Update: If you liked this post, the follow-up — Effect Without Effect-TS: Algebraic Thinking in Plain TypeScript — picks up where we left off and takes the ideas further.

I’ve been thinking about Alexis King’s Parse, don’t validate again. I do this quite regularly, actually, usually after staring at a TypeScript codebase that’s been quietly accumulating if (user.email) checks like barnacles. The post is from 2019, and the advice (or rather principle) is way older than that. And yet most TypeScript I read — including, embarrassingly, plenty I’ve written — still validates instead of parsing.

The pitch, if you haven’t read it (you should): a validator says “this thing is fine, please continue.” A parser says “give me a blob, and I’ll either give you back a more precise type or tell you why I can’t.” The difference sounds academic until you realize that validators throw away information the moment they finish running, while parsers preserve what they learned by encoding it in the type. Once you’ve parsed a string into an EmailAddress, the rest of your program never has to wonder again. Peace of mind and more mental capacity for the fun stuff.

In Haskell or Elm or F# this is just how you write code. The language pulls you toward it. In TypeScript… it doesn’t. TypeScript will happily let you do the right thing, but it won’t insist, and it won’t even gently nudge. If anything, structural typing actively undermines the whole game.

Let me show you what I mean.

The validator we’ve all written