functional-ts

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Functional Domain Modeling in TypeScript

TypeScript中的函数式领域建模

Principles for writing domain models in server-side TypeScript. Instead of class-based OOP, this approach maximizes the TypeScript type system through a functional style.
编写服务端TypeScript领域模型的原则。该方法摒弃基于类的OOP,通过函数式风格充分利用TypeScript的类型系统。

1. Type-Driven Domain Modeling

1. 类型驱动的领域建模

Represent states with discriminated unions using
kind
as the unified discriminant. Use
type
(not
interface
), companion objects, branded types,
Readonly<>
, function property notation, and one-concept-per-file structure.
Validation library detection: Check
dependencies
/
devDependencies
in the project's
package.json
for branded type syntax:
  • zod
    validation-libraries/zod.md
  • valibot
    validation-libraries/valibot.md
  • arktype
    validation-libraries/arktype.md
Details: domain-modeling.md
使用
kind
作为统一判别符,通过判别联合表示状态。使用
type
(而非
interface
)、伴生对象、品牌类型、
Readonly<>
、函数属性表示法,以及“一个概念对应一个文件”的结构。
验证库检测: 检查项目
package.json
中的
dependencies
/
devDependencies
,识别品牌类型语法对应的库:
  • zod
    validation-libraries/zod.md
  • valibot
    validation-libraries/valibot.md
  • arktype
    validation-libraries/arktype.md
详情:domain-modeling.md

2. State Transitions via Functions

2. 基于函数的状态转换

Express state transitions with pure functions. The argument type constrains valid source states, and the return type makes the target state explicit. Invalid transitions become compile errors. Use
assertNever
for exhaustiveness checking.
Details: state-modeling.md
使用纯函数表达状态转换。参数类型约束有效的源状态,返回类型明确目标状态。无效转换会成为编译错误。使用
assertNever
进行穷尽性检查。
详情:state-modeling.md

3. Error Handling — Railway Oriented Programming

3. 错误处理——面向铁路编程

Do not throw exceptions; treat errors as values using the Result type. Define error types as discriminated unions so callers can handle them exhaustively.
Library detection: Check
dependencies
/
devDependencies
in the project's
package.json
:
  • neverthrow
    result-libraries/neverthrow.md
  • byethrow
    result-libraries/byethrow.md
  • fp-ts
    result-libraries/fp-ts.md
  • option-t
    result-libraries/option-t.md
Details: error-handling.md
不要抛出异常;使用Result类型将错误视为值。将错误类型定义为判别联合,以便调用者可以穷尽地处理它们。
库检测: 检查项目
package.json
中的
dependencies
/
devDependencies
  • neverthrow
    result-libraries/neverthrow.md
  • byethrow
    result-libraries/byethrow.md
  • fp-ts
    result-libraries/fp-ts.md
  • option-t
    result-libraries/option-t.md
详情:error-handling.md

4. Boundary Defense

4. 边界防护

Validate external inputs (API requests, DB results, file reads) with validation library schemas at runtime. Trust types inside the domain layer. Do not use type assertions (
as
). Apply
Sensitive<T>
wrapper to PII fields.
Details: boundary-defense.md
在运行时使用验证库模式验证外部输入(API请求、数据库结果、文件读取)。信任领域层内部的类型。不要使用类型断言(
as
)。对PII字段应用
Sensitive<T>
包装器。
详情:boundary-defense.md

5. Declarative Style

5. 声明式风格

Write array transformations declaratively using
filter
/
map
/
reduce
with companion object predicates. Model domain events as immutable records.
Details: declarative-style.md
使用
filter
/
map
/
reduce
结合伴生对象谓词,以声明式方式编写数组转换。将领域事件建模为不可变记录。
详情:declarative-style.md

6. Test Data

6. 测试数据

Define test data with
as const satisfies Type
to preserve discriminant literal types and prevent widening.
Details: test-data.md
使用
as const satisfies Type
定义测试数据,以保留判别符字面量类型并防止类型拓宽。
详情:test-data.md

Applying These Principles

这些原则的应用

These are recommendations, not strict rules. You may use your judgment based on context, but if you deviate from a principle, explicitly state the reason in a comment.
Typical justified reasons to deviate:
  • An external library requires class inheritance
  • Immutable object creation cost is a performance concern
  • A different pattern has been adopted by team agreement
这些是建议,而非严格规则。你可以根据上下文做出判断,但如果偏离某个原则,请在注释中明确说明原因。
合理偏离的典型原因:
  • 外部库要求类继承
  • 不可变对象创建成本存在性能问题
  • 团队已一致采用其他模式