程序为什么总想把人留住:类型系统的边界与奖励设计的诱惑其实是同一件事

Nan Wang

Hatched by Nan Wang

Jun 04, 2026

1 min read

68%

0

你以为程序在“检查正确性”,其实它也在“制造预期”

为什么有些系统让人用得很安心,有些系统却让人一不小心就停不下来?表面上看,一个话题属于编程语言基础,一个话题属于产品成瘾机制,似乎八竿子打不着。可如果你把它们放在一起,会发现它们都在回答同一个问题:一个系统应该在多大程度上让人感到确定,还是持续感到悬念?

这不是纯技术问题,也不是纯心理学问题,而是关于边界设计的问题。TypeScript 里的类型、元组、枚举、断言、null 和 undefined 的规则,本质上是在给程序设边界,告诉你哪些事情在编译时就该被确定下来,哪些地方可以先放行。而游戏和产品里的奖励机制,则是在边界另一端做文章,故意留出“不确定性”,让人对下一次回报产生期待。

好的系统,不是把一切都变得确定,而是知道哪些地方必须确定,哪些地方可以有意保留悬念。

这句话几乎可以同时解释代码质量和用户上瘾。前者追求的是认知安全,后者追求的是行为牵引。真正高级的设计,不是单纯消除不确定性,也不是无节制制造不确定性,而是精确地分配不确定性


一切上瘾感,都是对“不确定回报”的追逐;一切类型系统,都是对“不确定输入”的约束

先看产品侧。人会在深夜一局接一局地玩游戏,不只是因为奖励本身,而是因为奖励预期。当你知道“下一把也许会掉好装备,也许差一点就升段,也许再来一局就赢”,大脑并不等到奖励真正出现才兴奋,它会在“可能出现”那一刻提前被点燃。最强的驱动力,往往不是满足,而是接近满足的临界状态。

这与代码中的类型系统形成了奇妙对照。TypeScript 通过 stringnumber[]Array<number>、元组、枚举,把原本模糊的数据世界切成了可预期的块。比如字符串模板让 Hello, my name is ${name} 这种表达既灵活又清晰,数组和泛型数组写法让“这是数字列表”这件事在编译阶段就变得明确,元组则进一步规定“这里不是一堆数字,而是一个顺序固定、位置含义不同的结构”。

这意味着,类型系统的价值不只是“报错”,更是消除不必要的悬念。当变量到底是字符串还是数字、数组还是元组、可空还是不可空不再靠猜,开发者的大脑就不必持续保留警觉状态。你可以把它理解为一种认知减负:把不该留到运行时的问题,提前在编译期结束掉。

从这个角度看,类型系统和奖励机制不是对立面,而是对同一件事的两种处理方式。一个在减少不确定性,一个在放大不确定性。一个让系统更可预测,一个让用户更想继续探索。


最危险的设计,不是有边界,而是边界刚好模糊到让人上瘾

很多人误以为,优秀体验来自“尽量顺滑”,于是要么把系统做得毫无阻力,要么把反馈做得极其频繁。可真正让人欲罢不能的,往往是边界不完全清楚的地方。你只差一点就能完成任务,只差一回合就能拿奖励,只差一个条件就能升级,于是你很自然地想“再试一次”。

这类设计在游戏中非常常见。下一轮奖励并不需要百分之百确定,只要有足够高的可能性,或者有足够近的距离感,行动就会被启动。可变奖励之所以有效,不是因为它比固定奖励更“值钱”,而是因为它在行为层面制造了一个更强的心理悬停区:你不确定会不会得到,但你知道有可能得到,而且可能就在下一次。

把这个逻辑移到代码世界,会出现一个非常有启发性的对照。TypeScript 里也存在“允许你先过去”的机制,比如类型断言。它不做运行时检查,只是在编译阶段告诉系统:“先按这个类型理解吧。”这类做法很像产品里的“模糊奖励”机制,都是为了效率,都是为了让流程不断开,但都带着风险。

关键区别在于,好的工程化系统会把这种风险控制在局部。类型断言并不意味着放弃类型安全,而是承认:在某些场景中,开发者拥有比编译器更多的上下文。换句话说,断言是一次有意识的越界,不是对边界的无视。这个细微差别很重要,因为它揭示了所有高质量系统的一条暗线:可以局部破坏确定性,但必须全局维护可解释性。

让人停不下来,不一定是因为刺激足够大,也可能是因为边界足够模糊。

产品如此,代码亦如此。模糊一旦失控,就会从“有趣”变成“难以维护”,从“吸引”变成“依赖”,从“灵活”变成“脆弱”。


可预测性不是平庸,恰恰是高级系统的道德底线

在很多讨论里,确定性常常被低估。人们更喜欢谈惊喜、创新、反馈回路、沉浸感,却忽略了一个事实:绝大多数长期可用的系统,都建立在可预测性之上。 没有它,用户会疲惫,开发者会出错,组织会失控。

想象一个电梯控制系统。如果它像游戏奖励一样随机工作,乘客会兴奋吗?不会,只会恐惧。再想象一个医疗系统,如果患者的用药逻辑是“有时有效,有时无效,但很刺激”,那它就不是产品设计,而是事故设计。这里的核心不是要否定变化,而是要承认:当系统承载的是安全、健康、责任时,确定性比惊喜更重要。

这正对应了固定奖励和可变奖励的分界。对于生理需求、安全需求,固定奖励往往更合理,因为用户要的是“稳定得到”,不是“也许得到”。而对于社交、认同、成就、探索这类更高层次需求,可变奖励的确更能驱动持续参与。这个区分很有启发性,因为它提醒我们,奖励机制不是越强越好,而是越贴近需求层级越好。

TypeScript 的类型设计也是如此。你不会希望核心业务逻辑里到处靠断言“赌一把”;你会更希望用明确的联合类型、元组结构、枚举值,把状态空间锁住。因为类型越明确,团队协作越容易,边界越清晰,未来维护越便宜。nullundefined 默认可赋值给很多类型,看起来方便,但也意味着系统会允许更多“缺席状态”混入核心流程。于是后来才会有更严格的空值检查理念,试图把“可能缺失”从默认常态变成显式决策。

这其实是一种价值判断:系统最应该宽容的,不是错误,而是不确定的来源;系统最应该严格的,不是表达,而是后果。


一个更实用的框架:把系统分成“确定层”和“诱导层”

如果把这两个领域的洞见合在一起,可以得到一个很实用的框架,叫做双层设计

1. 确定层,负责稳定与约束

这一层的目标是让系统的核心事实清晰、可验证、可维护。对程序来说,这意味着类型、结构、边界、状态都尽量显式化。对于用户体验来说,这意味着关键路径要可预期,重要动作要有明确反馈,失败要可理解。

比如:

  • 一个支付流程,金额类型不能含糊,状态流转必须明确。
  • 一个表单,必填项、可空项、默认值要清楚区分。
  • 一个任务系统,什么是已完成,什么是待处理,什么是失败重试,不能靠用户猜。

这层的原则是:尽量少留给想象,尽量多交给规则。

2. 诱导层,负责兴趣与持续参与

这一层允许适度的不确定性,但它必须建立在确定层之上。它可以是随机奖励、进度条、连续签到、下一关预告、阶段性反馈,也可以是某种轻量的探索机制。重点不是制造混乱,而是制造“值得继续”的感觉。

比如:

  • 在一个学习产品里,课程结构要固定,但下一题可能出现意外挑战。
  • 在一个游戏里,基本操作要稳定,但掉落和事件可以变化。
  • 在一个内容产品里,信息流规则要透明,但推荐结果可以保留新鲜感。

这层的原则是:让用户想继续,但不要让用户迷失。

这个框架有一个非常重要的启示:很多失败的产品和代码,都不是因为缺少功能,而是因为把两层搞混了。该确定的地方做得像抽奖,该随机的地方又死板得像表格。于是开发者天天补漏洞,用户天天猜规则。

设计的成熟,不是把所有地方都做得像机器,也不是把所有地方都做得像游戏,而是知道哪里该像合同,哪里该像冒险。


为什么这对开发者尤其重要:你写的不只是代码,也是行为环境

开发者常常以为自己只是在定义数据结构、处理类型和实现逻辑。事实上,你也在定义用户的心理节奏。一个输入框是否允许空值,一个状态切换是否明确,一个奖励出现是否可预测,这些都不是表面细节,而是在塑造人和系统的互动方式。

同样,产品设计师也常常以为自己只是在提升留存、活跃和时长。事实上,你在塑造一种习惯结构。固定奖励会训练人形成依赖,可变奖励会训练人大脑持续期待,而类型约束则像一条反方向的绳子,提醒你:有些自由会带来长期成本。

这里最值得警惕的是一种低级但常见的误解:把“更多不确定性”误认为“更有趣”,把“更多约束”误认为“更无聊”。 实际上,真正有趣的系统,往往是因为底层足够稳定,上层才敢变化。真正可维护的系统,往往是因为关键边界足够严格,局部才有发挥空间。

你可以把这理解为建筑学里的承重结构和装饰层。承重结构必须可靠,装饰层才可以变化;如果把承重梁也做成随机机制,房子就不是创意,而是危险。


Key Takeaways

  1. 先分清你在管理什么。 如果是安全、金钱、身份、状态流转这类关键领域,优先减少不确定性,用类型、规则和显式结构约束它。

  2. 把“不确定性”留给真正需要它的地方。 探索、娱乐、学习动机和持续参与,可以适度使用可变奖励,但前提是底层规则必须稳定。

  3. 不要把类型断言当成偷懒工具。 它更像是一次受控越界,只在你拥有额外上下文时使用。越是核心路径,越要谨慎。

  4. 设计体验时,区分“确定层”和“诱导层”。 确定层负责可信赖,诱导层负责吸引力。两者混在一起,系统要么枯燥,要么失控。

  5. 问自己一个更深的问题: 这个系统是在帮助人更快地获得明确结果,还是在让人对结果持续保持期待?如果答案模糊,往往意味着设计也模糊。


结语:真正厉害的系统,不是让你一直惊喜,而是知道何时该确定,何时该悬而未决

我们常把技术和产品当作两个世界,一个追求正确,一个追求留存。可它们共享的底层逻辑,其实是对人类认知节奏的安排。类型系统让我们在代码中减少猜测,奖励机制让我们在行为中增加猜测。一个在建立秩序,一个在利用期待。

这并不意味着前者高尚,后者低级。更准确地说,它们分别对应了系统设计中的两种力量:约束的力量诱导的力量。前者让世界可计算,后者让世界可继续。最好的系统不是偏向其中一边,而是能够精准回答:什么必须被锁定,什么可以被悬置。

如果你把这个问题看明白了,你会发现自己以后再看一段代码、一个游戏机制、一个产品流程时,关注的就不再只是“它是否好用”,而是“它在训练我什么样的预期”。而一旦你开始问这个问题,你就已经比大多数设计者更接近系统的本质了。

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣
程序为什么总想把人留住:类型系统的边界与奖励设计的诱惑其实是同一件事 | Glasp