Syntax
const value = expression; // type is inferred automaticallyExamples
Basic Inference
TypeScript infers types from initial values without needing annotations.
let count = 10; // inferred as: number
let name = "Alice"; // inferred as: string
let items = [1, 2, 3]; // inferred as: number[]
// count = "ten"; // Error - TypeScript remembers count is a number, even without an explicit annotationContextual Typing and Return Type Inference
TypeScript also infers types based on how a value will be used, and infers function return types.
window.addEventListener("click", (event) => {
console.log(event.button); // "event" is inferred as MouseEvent from context - full autocomplete works
});
function add(a: number, b: number) {
return a + b; // return type inferred as: number, no annotation needed
}Best practices
- Let TypeScript infer types for local variables initialized with an obvious value - explicit annotations there are usually redundant noise
- Still explicitly annotate function parameters, since TypeScript cannot infer those from usage the way it can return types
- Explicitly annotate a variable's type when it starts as one value but needs to later hold a broader type, like let result: string | null = null
- Use your editor's "hover to see inferred type" feature regularly - it is the fastest way to build intuition for how TypeScript reasons about your code
At a glance
- Purpose
- Static types for JavaScript
- File extension
- .ts ยท .tsx
- Runs in
- Compiled to JavaScript
- Usually used with
- JavaScript and its ecosystem
Specifications & further reading
Related TypeScript documentation
Basic Types
TypeScript extends JavaScript with static types, letting the compiler catch type errors before code ever runs. Beyond the familiar string, number, and boolean, TypeScript adds any (disables checking entirely), unknown (a safer any that requires narrowing), void (a function returning nothing), and never (a value that can never occur, like a function that always throws).Type Aliases
The type keyword creates a named alias for any type - not just object shapes like interface, but also unions, primitives, tuples, and function signatures. Type aliases make complex types reusable and give them a meaningful name, improving both readability and error messages.Union and Intersection Types
A union type (A | B) means a value can be either type A or type B. An intersection type (A & B) means a value must satisfy both A and B simultaneously, combining their members into one type. Unions are common for values with a few valid states; intersections are common for combining smaller, focused types into a larger one.Literal Types
Literal types narrow a type down to one specific, exact value rather than a general category - "success" instead of string, or 200 instead of number. They are most useful combined with union types, letting you precisely constrain a value to a specific set of allowed options, catching typos and invalid values at compile time.
TypeScript extends JavaScript with static types, letting the compiler catch type errors before code ever runs. Beyond the familiar string, number, and boolean, TypeScript adds any (disables checking entirely), unknown (a safer any that requires narrowing), void (a function returning nothing), and never (a value that can never occur, like a function that always throws).Type Aliases
The type keyword creates a named alias for any type - not just object shapes like interface, but also unions, primitives, tuples, and function signatures. Type aliases make complex types reusable and give them a meaningful name, improving both readability and error messages.Union and Intersection Types
A union type (A | B) means a value can be either type A or type B. An intersection type (A & B) means a value must satisfy both A and B simultaneously, combining their members into one type. Unions are common for values with a few valid states; intersections are common for combining smaller, focused types into a larger one.Literal Types
Literal types narrow a type down to one specific, exact value rather than a general category - "success" instead of string, or 200 instead of number. They are most useful combined with union types, letting you precisely constrain a value to a specific set of allowed options, catching typos and invalid values at compile time.