[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Task](https://evolu.dev/docs/api-reference/common/Task) › Task

```ts
type Task<T, E, D> = (run: Run<D>) => Awaitable<Result<T, E>>;
```

Defined in: [packages/common/src/Task.ts:857](https://github.com/evoluhq/evolu/blob/ecbac001e0c18bbc45b44715f49ecc3a768c5ec9/packages/common/src/Task.ts#L857)

A function passed to [Run](https://evolu.dev/docs/api-reference/common/Task/interfaces/Run) that returns an [Awaitable](https://evolu.dev/docs/api-reference/common/Types/type-aliases/Awaitable)
[Result](https://evolu.dev/docs/api-reference/common/Result/type-aliases/Result) and declares its dependencies through `D`.

See the [Task overview](https://evolu.dev/docs/api-reference/common/Task).

### Example

A Task that can't fail with a domain error:

```ts

const greet: Task<string> = () => ok("Hello!");
const main: Task<string> = (run) => run(greet);

await using run = createRun();
assertOk(await run(main), "Hello!");

// Without domain errors, `run.ok` returns the Ok value.
assertEqual(await run.ok(main), "Hello!");
```

A Task that can fail with a domain error:

```ts
import {
  assertErr,
  createRun,
  err,
  type Task,
  type Typed,
} from "@evolu/common";

const findUser =
  (id: string): Task<string, UserNotFoundError> =>
  () =>
    err({ type: "UserNotFound", id });

interface UserNotFoundError extends Typed<"UserNotFound"> {
  readonly id: string;
}

await using run = createRun();
assertErr(await run(findUser("user-1")), {
  type: "UserNotFound",
  id: "user-1",
});
```

A Task with dependencies:

```ts

interface Config {
  readonly greeting: string;
}

interface ConfigDep {
  readonly config: Config;
}

const greet: Task<string, never, ConfigDep> = (run) =>
  ok(`${run.deps.config.greeting}!`);

const config: Config = { greeting: "Hello" };
await using run = createRun({ config });
assertOk(await run(greet), "Hello!");
```

Start Tasks with `run(task)`, as shown above.

A Task can also be called directly as `task(run)`, but this is rarely needed.
The call executes the Task inline in the current Run, as if its body were
part of the parent Task, so it does not create a child Run. This is mainly
useful for Task composition helpers.