Type inference
TypeScript has a powerful feature called type inference, allowing it to automatically work out the type of a variable based on it's initial value. This means you don't always need to write type annotations explicitly.
How type inference works
When you initialize a variable with a value, TypeScript can infer the type:
let name = "Homer"; // TypeScript infers name as a string
let age = 39; // TypeScript infers age as a number
let likesDonuts = true; // TypeScript infers likesDonuts is a boolean
Even though we didn't write : string, : number, or : boolean, TypeScript knows what types these variables are based on the initial value.
Type inference vs type annotations
You can write the same code with explicit type annotations:
// Type annotations
let name: string = "Homer";
let age: number = 39;
let likesDonuts: boolean = true;
// Type inference
let name = "Homer";
let age = 39;
let likesDonuts = true;
Both approaches work the same way. Type inference can be preferred because it's less code to write, but type annotations can make your code more explicit and predictable.
When type inference works
Type inference works well when TypeScript can determine the type from the initial value:
Loading code...
// TypeScript infers these types automatically
let message = "TypeScript string";
let orders = 2;
let loggedIn = false;
let items = [1, 2, 3];
console.log(typeof(message));
console.log(typeof(orders));
console.log(typeof(loggedIn));
console.log(typeof(items));
When type inference doesn't work
Type inference won't work when no initial value is provided. With strict TypeScript settings (specifically when noImplicitAny is enabled), this will show an error:
// Error (with strict mode): Variable 'username' implicitly has an 'any' type
let username;
username = "Homer";
In this case you would need to provide a type annotation:
let username: string;
username = "Homer";
Or provide the initial value:
let username = "Homer";
Function return type inference
TypeScript can also infer the return type of functions:
Loading code...
function add(a: number, b: number) {
return a + b;
}
console.log(typeof(add(1,4)));
This is equivalent to:
function add(a: number, b: number): number {
return a + b;
}
Common practices
Many TypeScript developers use a mix of both:
- Use type inference for simple, obvious cases
- Use type annotations for function parameters and return types (for clarity)
- Use type annotations when the type isn't immediately obvious
Checking inferred types in your editor
You can see the type TypeScript has inferred by hovering over a variable in your code editor. Most modern editors (like VS Code) will show you the inferred type when you hover. For example, let username; will show as let username: any.
Type inference is a powerful and useful feature that makes TypeScript code cleaner and easier to write, while still maintaining type safety.