From typescript
ACTIVATE when modeling DDD aggregates, domain logic, or business rules in TypeScript using functional patterns. ACTIVATE for 'aggregate', 'smart constructor', 'make', 'validation pipeline', 'enrichment', 'domain handler'. Covers: immutable aggregates as readonly types (not classes), curried domain operations, smart constructors (make* prefix), validation/enrichment pipelines, handler orchestration pattern. DO NOT use for: infrastructure code, general FP patterns (see ts-functional), OOP modeling (see ts-oop).
How this skill is triggered — by the user, by Claude, or both
Slash command
/typescript:ddd-ts-fpThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Model aggregates as immutable types** with pure curried functions, not classes with methods:
Model aggregates as immutable types with pure curried functions, not classes with methods:
// Immutable type + curried functions
type Receipt = {
readonly id: ReceiptId;
readonly tenantId: TenantId;
readonly addresses: readonly Address[];
readonly period: Period;
readonly amount: number;
readonly createdAt: Date;
};
const addAddress =
(address: Address) =>
(receipt: Receipt): Receipt => ({
...receipt,
addresses: [...receipt.addresses, address],
});
Each operation is a curried function that returns a new aggregate (or a Result). Compose with pipe and chain.
When implementing aggregate operations, pipe composition, or nested immutable updates, read
references/ddd-functional-examples.mdfor complete patterns with pure and fallible transformations.
make prefix: curried factory function that captures context and returns a specialized function, usable directly in a pipe:
const makeAddress =
(addressId: string, createdAt: Date) =>
(command: AddAddressCommand): Result<Address, DomainError> =>
ok({ id: addressId, street: command.street, city: command.city, ... });
| Rule | Convention |
|---|---|
| Prefix | make |
| Signature | make*(context) => (input) => output |
| Return | Often Result<T, E>, sometimes T directly |
| Position | End of pipeline (after validations) or start of workflow |
When creating smart constructors for domain objects, read
references/ddd-functional-examples.mdfor complete examples and pipeline integration.
Validate incoming data via a chain of composable validators. Stops at first error:
type Validator<T> = (input: T) => Result<T, DomainError>;
// Composition
const validateCreateReceipt = (cmd) =>
pipe(cmd, validatePeriod, chain(validateAmount), chain(validateLease));
Transform external data into domain objects via progressive enrichment. Each step enriches or transforms the command.
| Aspect | Validation | Enrichment |
|---|---|---|
| Purpose | Verify constraints | Transform / complete data |
| Source | Internal data (domain) | External data (API, message broker) |
| Position | Before business logic | At system boundary |
When building validation or enrichment pipelines, read
references/ddd-functional-examples.mdfor complete pipeline implementations with enrichers.
The handler orchestrates: retrieval, validation, transformation, persistence.
Flow: validate -> load aggregate -> domain logic (pure) -> persist.
When writing domain handlers, read
references/ddd-functional-examples.mdfor the complete handler pattern with error handling.
| Rule | Convention |
|---|---|
| Aggregate | Immutable readonly type, no class |
| Operations | Pure curried functions |
| Smart Constructor | make*(context) => (input) => output |
| Updates | Spread operator, never mutate |
| Composition | pipe(aggregate, op1, op2, op3) |
| Fallible operations | pipe(aggregate, op1, chain(op2)) |
| Validation | Composable Validator<T> pipeline |
| Enrichment | Pipeline at system boundary |
| Handler | Orchestrator: validate -> load -> domain -> persist |
npx claudepluginhub fabiensalles/claude-marketplace --plugin typescriptGuides FP domain modeling with algebraic data types, smart constructors, primitive wrappers, and type-level validation to make illegal states unrepresentable.
Applies DDD tactical patterns using entities, value objects, aggregates, repositories, and domain events to enforce explicit invariants in domain code.
Models state machines, discriminated unions, Result/Option types, and branded types in TypeScript for type-safe domain modeling.