
JavaScript và TypeScript hiện đại phải đối mặt với nỗi đau: lỗi thời gian chạy không thể dự đoán, quản lý trạng thái phức tạp, và cảm giác không thể tin tưởng vào code khi cần mở rộng. Thư viện Effect TS (tên trước là Effect) đưa ra giải pháp cách mạng: viết TypeScript như một ngôn ngữ function pure, với error handling, dependency injection và tracing được tích hợp sẵn ở mức kiểu.
<!– IMG: Sơ đồ Effect type system hiển thị Effect và các toán tử –>
Vấn đề Effect TS giải quyết
Trong TypeScript truyền thống, chúng ta thường gặp các mô hình anti-pattern sau:
- Try-catch lẫn nhau: Chẳng hạn như
try { await api() } catch (e) { throw new Error('API failed: ' + e.message) }khiến mất thông tin lỗi gốc - Promise.all brittle: Một request thất bại làm toàn bộ batch crash, không thể partial success
- Hidden dependencies: Funciton phụ thuộc vào biến toàn cục, context, hoặc service locator khó trace
- Không có tracing: Khi sản xuất có lỗi, không biết request đi qua service nào, bao nhiêu lần retry
<img decoding="async" width="800" height="450" class="wp-image-7000" src="https://chuhung.net/wp-content/uploads/2026/08/img_2_1-78.jpg" alt="Effect type system diagram: Effect với ba tham số generic” />
Cơ bản về Effect type
Effect TS định nghĩa Effect với ba tham số generic:
- Success: Kiểu giá trị trả về thành công (ví dụ:
string,number,User) - Error: Kiểu lỗi có thể xảy ra (ví dụ:
ApiError,ValidationError,nevernếu không thể fail) - Requirements: Các dependencies cần thiết để effect này chạy (ví dụ:
Console | Configcho việc đọc config và in log)
Ví dụ đơn giản đọc nhiệt độ từ 4 thành phố:
import { Effect } from "effect"
const readTemperature = (city: string): Effect.Effect =>
Effect.tryPromise({
try: () => fetch(`http://api.weather.com/${city}`).then(res => res.json()).then(data => data.temp),
catch: (e) => new Error(`Failed to fetch ${city}: ${e}`)
})
const program = Effect.all([
readTemperature("New York"),
readTemperature("Berlin"),
readTemperature("Tokyo"),
readTemperature("London")
])
Effect.runPromise(program).then(console.log)
// Output: [22.5, 18.3, 25.1, 19.8] hoặc lỗi được typed chính xác
Cơ chế Structured Concurrency – So sánh với Promise.all
Một trong những tính năng mạnh mẽ nhất của Effect TS là Structured Concurrency giúp quản lý lifecycle của các tác vụ song song an toàn và predictable.
| Tình huống | Promise.all | Effect.all |
|---|---|---|
| Tất cả thành công | Trả về mảng kết quả | Trả về mảng kết quả |
| Một task thất bại | Ngay lập tức reject, hủy bỏ các task còn lại | Chờ tất cả hoàn thành, trả về raccol lỗi hoặc partial results tùy cấu hình |
| Need timeout/cancellation | Phức tạp, cần AbortController + Promise.race | Đa tích hợp sẵn qua Effect.withTimeout, Effect.timeout |
| Retry logic | Phải viết vòng lặp try/catch | Có sẵn Effect.retry với policy (exponential backoff, max attempts) |

Built-in solutions cho những bài toán khó
Effect TS tích hợp sẵn các giải pháp cho những vấn đề thường gặp trong hệ thống production:
Typed Errors
Thay vì unknown hoặc Error, bạn có thể định nghĩa lỗi chính xác:
// Định nghĩa lỗi riêng
const ValidationError = Effect.fail(new ValidationError({ field: "email", reason: "invalid format" }) as const)
// Type: Effect.Effect
Dependency Injection
Thay vì import trực tiếp hoặc sử dụng container, Effect TS sử dụng type-level dependencies:
interface UserService {
getUser: (id: string) => Effect.Effect
}
const getUserProfile = (id: string): Effect.Effect =>
Effect.gen(function*() {
const service = yield* Effect.service(UserService)
const user = yield* service.getUser(id)
return { ...user, profileComplete: !!user.bio }
})
Built-in Tracing và Logging
Mỗi effect tự động tạo span cho distributed tracing (tích hợp với OpenTelemetry, Jaeger, Datadog):
const apiHandler = Effect.gen(function*() {
yield* Effect.logInfo("Starting request processing")
const userId = yield* Effect.service(UserIdFromHeader)
const user = yield* UserRepository.findById(userId)
yield* Effect.logDebug("User found", { userId: user.id })
return user
})

Effect trong AI era
Với sự bùng nổ của AI agents và LLM-powered applications, Effect TS thể hiện nhiều ưu điểm đặc biệt:
- LLM-friendly: Cấu trúc deklaratif, type annotations phong phú giúp AI hiểu và sinh code chính xác hơn
- Deterministic testing: Nhờ effect pure, việc mock dependencies và kiểm tra các đường dẫn code trở nên đơn giản
- Supervision hierarchy: Giống Erlang OTP, Effect cho phép supervision trees để tự động khởi động lại các service bị lỗi
- Workflow engine:
Effect.Workflowcho phép tạo long-running process có checkpoint và replay khả năng
So sánh với các lựa chọn khác
| Feature | Zod | io-ts | Effect TS |
|---|---|---|---|
| Schema validation | ✅ | ✅ | ✅ (qua Effect.Schema) |
| Error handling | ❌ | ❌ | ✅ (typed errors) |
| Dependency injection | ❌ | ❌ | ✅ (type-level) |
| Structured concurrency | ❌ | ❌ | ✅ |
| Built-in tracing | ❌ | ❌ | ✅ |
Bắt đầu với Effect TS
Cài đặt đơn giản qua npm:
npm install effect
# Hoặc để thử nghiệm release candidate
npm install effect@rc
Documentation chi tiết tại Effect Website, bao gồm:
- Tutorial: Từ basic đến advanced patterns
- API Reference: Tất cả các effect và combinators
- Guides: Testing, debugging, performance tuning
- LLM Guide: Hướng dẫn sử dụng Effect với AI-assisted development
Kết luận
Effect TS không chỉ là một thư viện utility khác – đây là một lập trình paradigm mới cho TypeScript, mang lại tính an toàn, khả năng mở rộng và sự tinh tế mà các ngôn ngữ function pure như Haskell hoặc Scala đã chứng minh qua thập kỷ. Nếu bạn đang xây dựng hệ thống production TypeScript, đặc biệt là trong bối cảnh AI agents và microservices, Effect TS đáng đầu tư thời gian để học và áp dụng.
Nguồn: Effect Official Website, Effect Documentation, Effect GitHub
