TypeScript is created with an emphasis on safe development without excessive explicit types: most types of variables, parameters, and return values can be inferred automatically by the compiler. The type inference system allows you to write code almost like in JavaScript while maintaining strict typing, which significantly speeds up development and reduces the number of errors.
Type inference does not always guarantee that the type inferred is what the developer expects. Situations arise when the inferred type becomes too broad (any or unknown), or conversely, overly strict. This leads to either unnecessary restrictions or the absence of type checks, which is unsafe in both cases.
TypeScript automatically infers the type based on assignments or from the return value of a function if the type is not explicitly defined. You can manage the inference using explicit type declarations, type assertions, generics, and special utilities (ReturnType, Parameters, etc.). Working with complex structures requires special control: if the type is complex or unclear, it is better to specify it explicitly.
Example code:
let a = 5; // number (will infer automatically) function sum(x = 4, y = 3) { // x: number, y: number return x + y; // return: number } // Type inference error function getData(flag) { if (flag) return 123; // no return in the other branch — return type: number | undefined } // It’s better to specify explicitly: function getData(flag: boolean): number | undefined { if (flag) return 123; }
Key features:
True/False: Type inference always gives the type that the developer expects
False. Sometimes the type is broader or narrower, especially for arrays/objects/union return values (number | undefined is a common surprise).
If you do not specify the type in an object, TypeScript will always maintain the exact structure
No, without as const, the structure will be "widened"; with as const it will be readonly with literal types.
const obj = { kind: "duck" }; // obj: { kind: string } const obj2 = { kind: "duck" } as const; // obj2: { readonly kind: "duck" }
If a type is not specified for an array, TS always knows its composition
No, by default TypeScript makes the array as "broad" as possible — for example, let arr = [1, 'a'] will be (string | number)[], not a tuple.
as const or explicit types for constant objects.The backend returns a response object { data: [] }, the type is not explicitly specified, TypeScript infers the type for data as any[]. At some point, data becomes an array of strings — the error only surfaces in production.
Pros:
Cons:
In the project, it is accepted to always explicitly specify the return types of functions and complex structures, using as const for constants. Any change in structure is checked by the compiler.
Pros:
Cons: