@deessejs/fp

中文文档
5.0.1发布于 2026/10/07MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 2888

Functional Programming Utilities for TypeScript

原始使用文档
文档目录20 节
  1. What's included
  2. Why this stack
  3. Quick start
  4. Prerequisites
  5. Install
  6. Usage
  7. Engine compatibility
  8. Available commands
  9. Workspace (root)
  10. Package: @deessejs/fp
  11. App: web
  12. Compatibility
  13. Peer dependencies
  14. Engines
  15. Project structure
  16. Publishing
  17. Architecture notes
  18. Contributing
  19. License
  20. Support

@deessejs/fp

Lightweight, type-safe functional programming utilities for TypeScript. Result, Maybe, Try, Unit, and friends — ESM-only, no runtime dependencies, designed for first-class interoperability with @deessejs/errors.

License CI Stars npm

Documentation

Sibling projects: @deessejs/errors provides error types that integrate natively with @deessejs/fp's Result and Try. Install them together to get a complete error-handling story without glue code. Used internally at deessejs.com.


What's included

LayerWhat you getWhy it matters
Result<T, E>ok, err, pattern matching, sequencingType-safe error handling without exceptions or nulls.
Maybe<T>some, none, maybe, map, getOrElseOptional values that compose.
Try<T>try, tryAsync, conversion to ResultWrap throwing functions in a typed shell.
UnitThe unit type for void-returning operationsExpress "no value" without null or undefined.
Functional utilitiespipe, flow, identity, constant, flip, tupledCompose functions without ad-hoc helpers.
Async utilitiessleep, retry, timeout, QueueTime-based primitives that compose with Result.
Predicate utilitiesPredicate, Refinement, not, and, orFirst-class predicates and type guards.
Collection typesContext, Sequence, Collection, async iterator helpersSequence operations over various sources.
Generator compositiongen() with yield*Async flow control that reads like sync code.
@deessejs/errors integrationAll Result constructors accept @deessejs/errorsNo string-error footguns — use real error types.

Why this stack

  • Simple by default. No over-engineering, no fancy type gymnastics. Just the primitives you need to write cleaner code.
  • ESM-only. Modern packaging, no CJS shim, no module/main duplication.
  • Zero runtime dependencies. The only peer dep is @deessejs/errors, which is opt-in. The library itself is dependency-free.
  • TypeScript 6 first-class. Strict types, no any leakages, full inference. JSDoc where types alone are not enough.
  • Lockfile-clean pnpm workspaces. A single pnpm install rebuilds, lints, types, and tests the whole monorepo.
  • Real testing. Vitest, with coverage and integration tests against @deessejs/errors.

Quick start

Prerequisites

  • Node.js 22.14.0+ (engines.node enforced)
  • pnpm 10+ for development (corepack enable if not installed)
  • TypeScript 6+ for consumers (the package emits dist/*.d.ts)

Install

# Install @deessejs/fp with its optional sibling, @deessejs/errors.
# See https://github.com/deessejs/errors
npm install @deessejs/fp @deessejs/errors

@deessejs/errors is optional — install it if you want Result<T, E> to carry typed errors instead of strings.

Usage

import { ok, err, some, none, maybe, pipe } from '@deessejs/fp';

// Result: represent values that may have failed
const divide = (a: number, b: number) => (b === 0 ? err('Division by zero') : ok(a / b));

const result = divide(10, 2);
result.match({
  ok: (value) => console.log(`Result: ${value}`),
  err: (error) => console.error(`Error: ${error}`),
});

// Maybe: represent optional values
const user = { name: 'Alice', address: { city: 'Paris' } };
const city = maybe(user.address?.city)
  .map((c) => c.toUpperCase())
  .getOrElse('Unknown');

// pipe: compose functions without glue
const trim = (s: string) => s.trim();
const uppercase = (s: string) => s.toUpperCase();
const processed = pipe('  hello  ', trim, uppercase);

Engine compatibility

RuntimeMinimum version
Node.js22.14.0
pnpm10 (for development)
TypeScript6.0

ESM-only. Consumers using a CJS resolver need to use dynamic import() or migrate to ESM.

Available commands

Workspace (root)

CommandWhat it does
pnpm buildBuild every workspace
pnpm testRun all tests in watch mode
pnpm test:runRun all tests once
pnpm lintLint every workspace
pnpm type-checkType-check every workspace
pnpm formatFormat with Prettier

Package: @deessejs/fp

CommandWhat it does
pnpm --filter @deessejs/fp buildBuild dist/
pnpm --filter @deessejs/fp testRun vitest in watch mode
pnpm --filter @deessejs/fp test:runRun vitest once
pnpm --filter @deessejs/fp type-checktsc --noEmit
pnpm --filter @deessejs/fp lintRun ESLint

App: web

CommandWhat it does
pnpm --filter web devStart the docs site in dev mode
pnpm --filter web buildBuild the docs site

Compatibility

Peer dependencies

PackageRequiredNotes
@deessejs/errorsOptional, peer >=1.0.0Required if you want err() to accept typed errors. Listed as a devDependency for testing.

Engines

FieldValue
engines.node>=22.14.0
packageManager[email protected]

Project structure

.
├── packages/
│   └── fp/                # The library — @deessejs/fp on npm
│       ├── src/           # Source code (ESM)
│       ├── dist/          # Build output (gitignored)
│       ├── vitest.config.ts
│       └── tsconfig.build.json
├── apps/
│   └── web/               # Documentation site (Next.js + Fumadocs)
├── docs/
│   ├── internal/          # Engineering plans, runbooks
│   │   ├── product/
│   │   └── versions/
│   └── AGENTS.md          # Agent guidance (CLAUDE.md redirects here)
├── pnpm-workspace.yaml
├── turbo.json             # Turborepo pipelines
├── .changeset/            # Changesets for versioning
└── README.md

Publishing

Releases are fully automated via Changesets + npm Trusted Publishing (OIDC). No long-lived NPM_TOKEN is required.

WhatHow
Bump versionAdd a .changeset/<topic>.md file with semver + description
Open the release PRchangesets-version.yml opens / updates a "Version Packages" PR from staging to main
PublishMerge the Version Packages PR → publish.yml runs → version bump committed → Trusted Publishing publishes to npm with provenance attestation
HotfixPush a tag vX.Y.Z to main → same workflow runs for the hotfix path
Rollback or deprecatePlanned: see docs/engineering/plans/release-pipeline-github-ui-setup.md

For the full pipeline design, see docs/engineering/plans/release-pipeline.md.

Architecture notes

  • ESM-only. The package exports ES modules. Consumers using legacy CJS resolvers must use dynamic import().
  • Strict types. Result.match requires both branches; Maybe.getOrElse requires a fallback. No partial type escapes.
  • Composition over inheritance. All primitives compose via pipe and flow. No class hierarchy, no extends.
  • Zero-runtime abstractions. No decorators, no reflection, no proxy traps. The library is straightforward to read in DevTools and node --prof.
  • Smoke-tested before publish. The release workflow runs a dynamic ESM import of the built artifact and verifies that key exports are present. A broken build fails the publish step before reaching npm.
  • @deessejs/errors is opt-in. The peer dep stays optional so consumers can adopt @deessejs/fp in isolation. Once @deessejs/errors is added, every err(error) call accepts a typed error.
  • One source of truth for auth-style errors. The apps/app/proxy.ts (in the broader deessejs monorepo, not in this repo) enforces email verification at the proxy level. @deessejs/errors errors are caught and translated to HTTP responses centrally.

Contributing

Open an issue to discuss larger changes. For typos, broken links, and small fixes, PRs are welcome.

Before submitting a PR:

  1. Run pnpm --filter @deessejs/fp test:run and pnpm --filter @deessejs/fp lint.
  2. Add a .changeset/<topic>.md if the change is user-facing (patch / minor / major).
  3. Update docs/internal/product/README.md if the API surface changes.

License

MIT. See the LICENSE file for details.

Support

版本与发布记录

@deessejs/fp 共发布 24 个版本,首次发布于 2026/04/08;过去 12 个月发布了 24 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
5.0.1latest2026/10/071 个月前
5.0.02026/10/071 个月前
2.0.12026/10/071 个月前
2.0.02026/10/071 个月前
1.3.02026/08/202 个月前
1.2.92026/08/132 个月前

其他发布通道:canary → 0.0.0-canary-20260806122825。

关于 @deessejs/fp 的常见问题

@deessejs/fp 是什么?

Functional Programming Utilities for TypeScript

如何安装 @deessejs/fp?

在项目目录运行 npm install @deessejs/fp,或使用 pnpm add / yarn add / bun add。

@deessejs/fp 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@deessejs/fp 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@deessejs/fp 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.14.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@deessejs/fp 可以商用吗?

@deessejs/fp 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@deessejs/fp 的下载量有多少?

根据 npm 官方下载统计,@deessejs/fp 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,888 次,日均约 96 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@deessejs/fp 还在维护吗?

最新版本 5.0.1 发布于 2026/10/07(1 个月前);至今共发布 24 个版本,其中过去 12 个月发布了 24 个;首次发布于 2026/04/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。