# @typescript-eslint/typedef

> Require type annotations in the places you choose

TypeScript infers most types. Some teams still want them written out in certain places, for example on every parameter, so a reader doesn't need an editor to see them.

Every option is off by default, so this rule reports nothing until you turn on at least one.

typescript-eslint has deprecated this rule and no longer recommends it.

## Examples

Reported with `parameter` and `arrowParameter` on:

{/* bad {"count": 2, "options": [{"parameter": true, "arrowParameter": true}]} */}
```ts
function greet(name) {
  return `Hello ${name}`;
}

const double = value => value * 2;
```

Not reported:

{/* good {"options": [{"parameter": true, "arrowParameter": true}]} */}
```ts
function greet(name: string) {
  return `Hello ${name}`;
}

const double = (value: number) => value * 2;
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `parameter` | `false` | Require a type on function and method parameters. |
| `arrowParameter` | `false` | Require a type on arrow function parameters. |
| `variableDeclaration` | `false` | Require a type on `const`, `let`, and `var`. Destructuring has its own options. |
| `variableDeclarationIgnoreFunction` | `false` | Don't require a type on a variable or a class property that's set to a function. |
| `arrayDestructuring` | `false` | Require a type on `const [a, b] = ...`. |
| `objectDestructuring` | `false` | Require a type on `const { a, b } = ...`. |
| `memberVariableDeclaration` | `false` | Require a type on class properties. |
| `propertyDeclaration` | `false` | Require a type on interface and type literal properties. |

Both are reported with `variableDeclaration`:

{/* bad {"count": 2, "options": [{"variableDeclaration": true}]} */}
```ts
const retries = 3;
const log = (message: string) => console.log(message);
```

Add `variableDeclarationIgnoreFunction` to leave functions alone. The variable in a `for...of` or `for...in` loop never needs a type:

{/* good {"options": [{"variableDeclaration": true, "variableDeclarationIgnoreFunction": true}]} */}
```ts
const retries: number = 3;
const log = (message: string) => console.log(message);

for (const attempt of [1, 2, 3]) {
  log(`attempt ${attempt}`);
}
```

Reported with `arrayDestructuring` and `objectDestructuring`:

{/* bad {"count": 2, "options": [{"arrayDestructuring": true, "objectDestructuring": true}]} */}
```ts
const [first] = [1, 2];
const { name } = { name: "Ada" };
```

The type goes after the pattern:

{/* good {"options": [{"arrayDestructuring": true, "objectDestructuring": true}]} */}
```ts
const [first]: number[] = [1, 2];
const { name }: { name: string } = { name: "Ada" };
```

Reported with `memberVariableDeclaration` and `propertyDeclaration`:

{/* bad {"count": 2, "options": [{"memberVariableDeclaration": true, "propertyDeclaration": true}]} */}
```ts
class Counter {
  count = 0;
}

interface Options {
  verbose;
}
```

## When not to use it

Annotations that repeat what TypeScript infers add noise, and `const mode: string = "dark"` loses the more precise type `"dark"`. To catch values that silently become `any`, turn on `noImplicitAny` in your `tsconfig.json` instead.
