Type inference lets the TypeScript compiler check code without requiring an annotation on every variable or function result. It derives types from initial values, expressions, and existing type information. An annotation on a method parameter can therefore help check a call even when the calling code has none. section 7.2.2 section 2.2.5
Follow a value through a calculation
In src/index.ts, `function calculateTax(amount: number) { return amount * 1.2; }` has an inferred `number` result. With `let price = 100`, both `calculateTax(price)` and the resulting `let taxAmount = ...` are checked as numbers; `let halfShare = taxAmount / 2` is a number too. Change the return expression to `(amount * 1.2).toFixed(2)`, and the inferred result becomes `string`. Dividing that result by 2 then produces a compiler error. JavaScript could coerce the string, but TypeScript flags the arithmetic instead. section 7.2.2
Inference also carries type information from a class definition into ordinary application code. A `TodoCollection.addTodo(task: string): number` call accepts a string and returns a number. Passing a `TodoItem` instead produces TS2345, even when the local variables in src/index.ts have no explicit annotations. Add annotations when they make the code easier to read; they are not needed at every use. section 2.2.5
Arrays depend on their initial values
`let prices = [100, 75, 42]` is inferred as `number[]`, and `let names = ["Hat", "Gloves", "Umbrella"]` as `string[]`. Those types carry into a `forEach` callback. An empty `let prices = []` gives the compiler no initial values to use. In the illustrated configuration it becomes `any[]`, allowing numbers and a string to be pushed without a type error. With `strictNullChecks: true`, the illustrated empty-array case instead infers `never[]` and rejects the push. Give an array an explicit type when it starts empty. section 9.2.1 section 9.2.3
Inference does not necessarily choose the shared superclass you intend for an array. An array initialized with two different subclasses can be inferred as a union of those subclasses; pushing a third subclass then fails. Declare the array as the superclass type when it must hold all three. The compiler responds to the types and shapes of the initial objects, not just the class hierarchy you have in mind. section 11.3.7
For conditional types, `infer` makes the inference request explicit. `type targetKeys<T> = T extends (infer U)[] ? keyof U : keyof T` obtains an array's element type before selecting its property keys. A similar conditional type uses `infer R` to obtain a function's result type. These patterns serve generic code; routine variable inference needs no `infer` keyword. section 13.6.6
When an inferred type is surprising, enable the `declaration` compiler option and inspect the emitted index.d.ts file in dist. It shows, for example, whether an array was declared as `number[]`, `any[]`, or a union of class types. section 7.2.2 section 9.2.1 section 11.3.7















