Effection is written in TypeScript and comes bundled with its own type
definitions. As such, it doesn't require any special setup to use in a
TypeScript project. This section only contains some helpful hints to make
the most out of the Effection related typings in your project.

## TL;DR

Use the `Operation` type for your operations

```ts
import type { Operation } from "effection";

export function* op(): Operation<number> {
  yield* sleep(10);
  return 5;
}
```

If you see a weird type like `Generator<Instruction, T>` or
`Iterable<Instruction,T>` or `IterableIterator<Instruction, T>`,
replace it with `Operation<T>`.

## Use Operations Everywhere

The foundation of Effection is the [`Operation<T>`][operation] type. This is the type that
it uses internally to represent all actions and resources, and it is the type
that you should both consume and return from your own functions.
For the most part, TypeScript will infer this for you, and you don't need
to worry about it. However, there are some cases you may want to give it a hint
that what you have is an operation, even though it will work without it.
This is because `Operation<T>` is effectively an
`Iterable<Instruction, T>`. This means that when you create this
shape naturally in your code, then it will correctly slot into other
operations, but it might be confusing when people look at types in
their IDE. Take the following generator function:

 ```typescript
 function* op() {
   yield* sleep(10);
   return 5;
 }
 ```

The natural inferred return type of this function is `Generator<Instruction,T>` which
 satisfies `Iterable<Instruction, T>` and so can be used as an operation,
 but it loses the higher-level intent of the operation.
 Instead, write `op()` like this:
 ```typescript
 function* op(): Operation<number> {
   yield* sleep(10);
   return 5;
 }
 ```
 By pinning the return type to `Operation<number>`, it communicates the intent
 of how the generator is to be used beyond just the literal shape of the
 generator itself.

 The same applies for Operation values:

```ts
const op = {
  *[Symbol.iterator]() {
    yield* sleep(10);
    return 5;
  }
}
```
Strictly speaking the type of `op` is:
```ts
{
  [Symbol.iterator](): Generator<Instruction, T, any>
}
```

While this is technically correct, and it will work if you use it as
an operation, it isn't particularly helpful to your end users. Instead, give
them a leg up, and make their editor's tooltip show that they can evaluate
it and expect to receive a number.

```ts
  const op: Operation<number> = {
  *[Symbol.iterator]() {
    yield* sleep(10);
    return 5;
  }
}
```

Now anybody using your operation won't have any doubt about what it is and how
they can use it.

[operation]: /api/v4/Operation
