Suggest an editImprove this articleRefine the answer for “Type inference with generics”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Type inference** for generics is the mechanism by which TypeScript analyzes the arguments passed to a function and substitutes the concrete type in place of `T` on its own, so you do not need to write `<string>`, `<number>`, and so on explicitly. **Key point:** when TypeScript cannot infer the type from the arguments (for example, from `null` or `undefined`), the type must be specified explicitly.Shown above the full answer for quick recall.Answer (EN)Image## What type inference means for generics When you call a function with a generic parameter, TypeScript **analyzes the arguments you pass** and **substitutes the type itself** in place of `T` (or other parameters). In other words, you do not need to explicitly write `<string>`, `<number>`, and so on - the compiler does it automatically. ### Example 1: basic type inference ```javascript function identity<T>(value: T): T { return value; } const a = identity("Hello"); // T = string const b = identity(42); // T = number ``` TypeScript sees that the argument `"Hello"` has type `string`, and substitutes `T = string` automatically. ### Example 2: inferring a type from several arguments ```javascript function merge<T, U>(a: T, b: U): T & U { return Object.assign({}, a, b); } const result = merge({ name: "Tim" }, { age: 25 }); // TypeScript infers T = { name: string }, U = { age: number } // The result has type { name: string; age: number } ``` Here `T` and `U` are inferred **from each argument separately**. TypeScript combines them with `&`. ### Example 3: inference from context (contextual inference) ```javascript function wrap<T>(value: T): { data: T } { return { data: value }; } const wrapped = wrap({ id: 1, name: "Tim" }); // T = { id: number; name: string } ``` TypeScript "sees" the structure of the passed object and infers the exact type. ### Example 4: partial inference ```javascript function pair<T, U = string>(first: T, second?: U): [T, U] { return [first, second as U]; } const p1 = pair(1); // T = number, U = string (default) const p2 = pair(true, false); // T = boolean, U = boolean ``` You can set a **default type** for a generic parameter - it is then used when TypeScript cannot infer the type from the arguments. ### Example 5: inferring the type from a function's return value ```javascript function makeArray<T>(item: T, times: number): T[] { return Array(times).fill(item); } const arr = makeArray(5, 3); // T = number → number[] ``` The type `T` is inferred from the first argument, `item`. ### Example 6: when inference does not work ```javascript function logValue<T>(value: T): void { console.log(value); } logValue(null); // T cannot be inferred precisely logValue(undefined); // same here ``` In such cases you need to specify the type explicitly: ```javascript logValue<string | null>(null); ``` ## How inference works under the hood TypeScript applies several strategies: 1. **From arguments → to type parameters** - analyzing the arguments and their types. 2. **From return type** - if the result type can be computed. 3. **Contextual typing** - analyzing the context where the function is used. Example of contextual inference: ```javascript const handler = <T>(value: T) => console.log(value); ["a", "b", "c"].forEach(handler); // TypeScript understands that T = string ``` ## Summary | What TS does | Example | Result | |---|---|---| | Infers a type from an argument | `identity(42)` | `T = number` | | Infers a type from several arguments | `merge({a: 1}, {b: 2})` | `T = {a: number}, U = {b: number}` | | Applies a default type | `pair(1)` | `U = string` | | Contextual inference | `["x"].forEach(handler)` | `T = string` | | Cannot infer the type | `logValue(null)` | must be specified explicitly |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.