TypeScript Generics and Function Types
TypeScript generics help you reuse functions and data types without discarding type information. Start with function signatures, then learn how type parameters connect inputs and outputs. Built-in utility types let you adapt types you already have.
These three fit together more tightly than their names suggest. A utility type such as ReturnType is a generic type applied to a function type, so the vocabulary of the first guide shows up in the last one. Read them in order if any of that is new.
TypeScript Generics Topics
- Typing Functions and Callbacks covers parameters, return types, optional and rest parameters, callback types, and where contextual typing saves you the annotation.
- Generic Functions and Types covers type parameters, inference at the call site, constraints with
extends, and defaults. - Utility Types covers the built-in transformers such as
Pick,Omit,Partial,Record, andReturnType, plus when a named type beats a clever one.
What Are TypeScript Generics?
TypeScript generics let a function, interface, or type alias accept type parameters. A type parameter preserves the relationship between a caller's input and the result without using any. Compare these two functions:
// a value parameter: the caller supplies the value
function identityValue(value: string): string {
return value;
}
// a type parameter: the caller supplies (or the compiler infers) the type
function identity<Value>(value: Value): Value {
return value;
}
const label = identity("draft");
const count = identity(3);
// hover in an editor shows:
// const label: "draft"
// const count: 3 The compiler read each call and filled Value in for you, which is inference doing the same job it does for ordinary variables. Those two results are literal types because the arguments were literals passed straight into an unconstrained type parameter; the same calls assigned through a wider annotation would widen to string and number.
The second half of the rule is that all of this disappears. Type parameters, constraints, and utility types are part of the type layer, so compilation erases them and the emitted JavaScript holds one plain function. That is why a generic cannot inspect its own type argument at runtime. There is nothing left to inspect. Checking what a value actually is remains a narrowing problem, which the types topic covers.
Common Pitfalls
- A type parameter used once: if
Tappears in exactly one position and nowhere else, it is usually not connecting anything, though a parameter used once can still capture a type for a later inference. The generics guide covers the test for whether a parameter is pulling weight. - Annotating callback parameters that infer: a callback passed straight into a typed parameter is contextually typed already. The functions guide shows where that inference applies and where it stops.
- Reaching for
anyto make a helper reusable: that stops checking the affected values and loses information about the return type. A type parameter keeps the caller's type instead of discarding it. - Nesting utility types until nobody can read them:
Partial<Pick<User, "email">>is fine once. Repeated in three files, it wants a name, as the utility types guide argues.
Frequently Asked Questions
What does T mean in TypeScript generics?
In TypeScript generics, T is a type parameter name, just as x can be a value parameter name. The single letter is a convention inherited from other languages, not a rule. GenericItem or ItemType compiles identically. Longer names usually read better once a helper takes more than one type parameter.
Do TypeScript generic calls need explicit type arguments?
TypeScript generic calls usually do not need explicit type arguments because the compiler can infer them from the supplied values. Some positions provide no inference candidate, and NoInfer deliberately excludes one. You supply it yourself when the call constrains nothing, or when you want a wider type than inference picked.
Do TypeScript generics slow down JavaScript at runtime?
TypeScript generics do not add runtime overhead to the JavaScript they produce. Type parameters disappear during compilation, leaving an ordinary function. The cost lands on the compiler and the editor, which is why deeply nested generic types can slow type checking while leaving runtime performance untouched.
Continue Learning TypeScript
- Start with TypeScript Types if annotations, interfaces, and unions are still new. Everything here builds on them.
- Move on to TypeScript Tooling for
tsconfig.json, the compiler flags that change how strict all of this is, React props, and API contracts. - Return to the TypeScript guide for the language overview and the full learning path.
Sources
-
[1]
More on Functions(typescriptlang.org)
-
[2]
Generics(typescriptlang.org)
-
[3]
Utility Types(typescriptlang.org)
Read Next
Parameter and return annotations, optional and rest parameters, named function types, and the contextual typing that removes most callback annotations.
Type parameters explained without the theory: what a generic buys you, how inference fills it in at the call site, constraints with extends, generic types, and defaults.
Should you learn TypeScript or JavaScript first? What TypeScript is used for and who uses it, whether it is worth it with AI agents, running it in Node, and a roadmap to every guide.