# TypeScript Type Inference & Best Practices

TypeScript is smart. You don't always need to annotate every variable with a type. **Type Inference** is the mechanism where the compiler automatically deduces the type of a variable or function return value based on the value assigned to it or the context in which it is used.

## 1. Basics of Inference

### Variable Initialization
When you declare a variable and initialize it immediately, TypeScript infers the type.

```typescript
let x = 3; 
// TypeScript infers 'x' is 'number'

let y = "hello";
// TypeScript infers 'y' is 'string'
```

### Function Return Types
TypeScript infers the return type of a function based on its `return` statements.

```typescript
function add(a: number, b: number) {
    return a + b;
}
// Inferred return type: number
```

## 2. Best Common Type

When an array is initialized with multiple types, TypeScript looks for a "best common type" that works for all candidates.

```typescript
let x = [0, 1, null];
// Inferred type: (number | null)[]

class Animal {}
class Rhino extends Animal {}
class Elephant extends Animal {}
class Snake extends Animal {}

let zoo = [new Rhino(), new Elephant(), new Snake()];
// Inferred type: (Rhino | Elephant | Snake)[]
// Note: It does NOT automatically infer 'Animal[]' unless you explicitly state it.
```

## 3. Contextual Typing

Contextual typing occurs when the type of an expression is implied by its location. A common example is event handlers.

```typescript
window.onmousedown = function(mouseEvent) {
    // TypeScript knows this is a MouseEvent because of 'onmousedown'
    console.log(mouseEvent.button); // OK
    // console.log(mouseEvent.kangaroo); // Error
};
```

## 4. Best Practices

### A. Rely on Inference for Local Variables
Don't clutter your code with obvious types.

**Bad:**
```typescript
const name: string = "Alice";
const age: number = 30;
```

**Good:**
```typescript
const name = "Alice";
const age = 30;
```

### B. Explicitly Type Function Parameters
TypeScript usually cannot infer parameter types (unless contextually typed). Always type them to avoid `any`.

### C. Explicitly Type Return Types for Public APIs
While TypeScript *can* infer return types, it is best practice to explicitly define them for exported functions or public class methods.
1.  **Documentation:** It makes the code self-documenting for consumers.
2.  **Safety:** It prevents accidental changes to the return type if implementation details change.
3.  **Speed:** The compiler doesn't have to do the work of inferring it.

### D. Enable `noImplicitAny`
Always keep `"noImplicitAny": true` in your `tsconfig.json`. This forces you to handle cases where inference fails (falling back to `any`), ensuring you maintain type safety.

[[programming/javascript/typescript/typescript]]