effect
1
总安装量
1
周安装量
#44066
全站排名
安装命令
npx skills add https://github.com/michaelvessia/nixos-config --skill effect
Agent 安装分布
opencode
1
codex
1
claude-code
1
gemini-cli
1
Skill 文档
Effect-TS Best Practices
Opinionated patterns for Effect-TS codebases. Effect provides typed functional programming with composable errors, dependency injection, and observability.
Critical Rules
- NEVER use
anyor type casts (as Type) – UseSchema.make()for branded types,Schema.decodeUnknown()for parsing - Don’t use
catchAllwhen error type isnever– No errors to catch - Never use global
Errorin Effect channels – UseSchema.TaggedErrorfor domain errors - Ban
{ disableValidation: true }– Lint against this - Don’t wrap safe operations in Effect – Only use
Effect.try()for throwing operations - Use
mapErrornotcatchAllCause– Distinguish expected errors from bugs - Never silently swallow errors – Failures MUST be visible in the Effect’s error channel E
Quick Reference
| Pattern | DON’T | DO |
|---|---|---|
| Service definition | Context.Tag |
Effect.Service with dependencies array |
| Error types | Generic Error |
Schema.TaggedError with context fields |
| Branded IDs | Raw string |
Schema.String.pipe(Schema.brand("@Ns/Entity")) |
| Running effects | runSync/runPromise in services |
Return Effect, run at edge |
| Logging | console.log |
Effect.log with structured data |
| Configuration | process.env |
Config with validation |
| Method tracing | Manual spans | Effect.fn("Service.method") |
| Nullable results | null/undefined |
Option types |
| State | Mutable variables | Ref |
| Time | Date.now(), new Date() |
Clock service |
Service Pattern
class UserService extends Effect.Service<UserService>()("UserService", {
dependencies: [DatabaseService.Default],
effect: Effect.gen(function* () {
const db = yield* DatabaseService
return {
findById: Effect.fn("UserService.findById")(
(id: UserId) => db.query(/* ... */)
),
}
}),
}) {}
// Usage - dependencies auto-provided
UserService.findById(userId)
Error Handling
// Define domain-specific errors
class UserNotFoundError extends Schema.TaggedError<UserNotFoundError>()(
"UserNotFoundError",
{ userId: UserId, message: Schema.String }
) {}
// Handle with catchTag (preserves type info)
effect.pipe(
Effect.catchTag("UserNotFoundError", (e) => /* handle */),
Effect.catchTag("AuthExpiredError", (e) => /* handle */)
)
Schema Pattern
// Branded ID
const UserId = Schema.String.pipe(Schema.brand("@App/UserId"))
// Domain entity with Schema.Class
class User extends Schema.Class<User>("User")({
id: UserId,
email: Schema.String,
createdAt: Schema.DateFromSelf,
}) {
get displayName() { return this.email.split("@")[0] }
}
Layer Composition
// Declare dependencies in service, not at usage
const MainLayer = Layer.mergeAll(
UserServiceLive,
AuthServiceLive,
DatabaseLive
)
// Run program
Effect.runPromise(program.pipe(Effect.provide(MainLayer)))
Detailed Guides
- Anti-Patterns – Forbidden patterns with fixes
- Error Patterns – Domain errors, rich context, HTTP mapping
- Schema Patterns – Branded types, transforms, validation
- Service Patterns – Effect.Service, dependency injection
- Layer Patterns – Composition, memoization, testing
- Observability Patterns – Logging, tracing, metrics
- SQL Patterns – Database integration, transactions
- Testing Patterns – effect-vitest, property testing, Testcontainers
- Atom Patterns – React state management with Effect
- RPC & Cluster Patterns – Distributed systems