When does TypeScript infer generic type arguments, and when must you pass them yourself?
TypeScript infers type arguments from the values you pass. You must write them explicitly when no argument carries the type, such as an empty array, a function with only a return type, or a call where you want a wider type than the inferred one.
Explain it simply
When you give a courier a parcel, he reads the label and knows where it goes. Generics work like that: pass "Asha" and the compiler decides T is string.
But if you send an empty box, there is no label. new Map() alone has nothing to read from, so you tell it: new Map<string, number>(). The same happens with functions like fetchJson<T>() whose type appears only in the return position.
Example
function identity<T>(x: T): T { return x; } const a = identity("hi"); // T inferred as "hi" -> a: "hi" const b = identity<string>("hi"); // T forced to string -> b: string
const empty = new Set(); // Set<unknown> const ids = new Set<number>(); // explicit ids.add(7);
async function getJson<T>(url: string): Promise<T> { const res = await fetch(url); return res.json() as Promise<T>; // T cannot be inferred from url } // const user = await getJson<{ name: string }>("/api/user");
const list = [] as string[]; // another way to declare empty array type
What to say in the interview
Inference works from arguments. When nothing in the call carries the type, like an empty collection or a return-only type parameter, or when I want a wider type than the literal inferred, I pass the type argument in angle brackets. Passing it for a fetch helper is also a promise to the compiler, not a check.
Common mistakes
- Believing getJson<User>() validates the response; it only asserts the type.