335 words
2 minutes
[Effect Services] 04. 类型化依赖管理

类型化依赖管理#

https://github.com/typeonce-dev/effect-getting-started-course

如果你现在检查 program 的类型,你可以注意到 Effect 内部有一个第三个类型参数

https://vmfiooakcvcmnormoutn.supabase.co/storage/v1/object/public/sandromaglione-com/blog-images/effect-dependency-type-first-example

TIP

Effect 类型参数

每个 Effect 都有 3 个类型参数:成功、错误和依赖。我们的程序依赖于 PokeApi 服务。

到目前为止,我们忽略了第三个类型参数,因为它总是 never(无依赖)。

当我们开始将服务组合在一起时,这个第三个参数将收集运行程序所需的所有依赖的联合类型

IMPORTANT

类型安全的依赖管理

最好的部分(再次)是类型安全。所有依赖都在 Effect 类型上声明。这确保了如果我们在运行最终程序时忘记提供依赖,我们会得到编译时错误。

如果我们尝试在 program 上执行 runPromise,我们会得到类型错误:

import { Effect } from "effect";
import { PokeApi } from "./PokeApi";

const program = Effect.gen(function* () {
  const pokeApi = yield* PokeApi;
  return yield* pokeApi.getPokemon;
});

///               👇 Error here
Effect.runPromise(program).then(console.log);
Type 'PokeApi' is not assignable to type 'never'.

这是因为 Effect 中的每个 run 方法都要求第三个类型参数为 never,意味着所有依赖都已被提供。

Effect.ts

export const runPromise: <A, E>(
  effect: Effect<A, E, never>,
  options?: { readonly signal?: AbortSignal } | undefined
) => Promise<A> = _runtime.unsafeRunPromiseEffect

我们如何提供依赖?这就是下一步!

[Effect Services] 04. 类型化依赖管理
https://0bipinnata0.my/posts/course/effect-beginners-complete-getting-started/effect-services/04-dependency-management-with-types/
Author
0bipinnata0
Published at
2025-08-30 17:48:34