Typeof Type Operator in TypeScript
The typeof type operator captures the TypeScript type of a runtime value. Learn how to use it with ReturnType, keyof, and other type operators for safer type derivations.
The TypeScript typeof type operator captures the type of a runtime value and lets you use that type in type annotations. It bridges the gap between values and types, so you do not have to manually rewrite types that already exist in your code.
JavaScript already has a typeof operator that runs at runtime and returns a string:
console.log(typeof "hello");This logs "string" at runtime. TypeScript adds a second use of the same keyword in type contexts. In a type position, typeof extracts the TypeScript type of a variable:
let message = "hello";
let copy: typeof message;The variable copy gets the type string because typeof message evaluates to the type of message. TypeScript infers it without you writing string explicitly.
For primitive values this is not very exciting. The operator becomes powerful when combined with other type operators and complex values.
Using typeof with Functions and ReturnType
One of the most common patterns is capturing a function's return type with ReturnType. You cannot pass a function name directly to ReturnType because it expects a type, not a value:
function getUser() {
return { id: 1, name: "Ada" };
}
type User = ReturnType<typeof getUser>;typeof getUser converts the function value into its type, and ReturnType extracts the return type. The resulting User type is { id: number; name: string }. If you change what getUser returns, the User type updates automatically.
This pattern is common when you have a function that constructs objects and you want a type alias that stays in sync without manual maintenance.
Capturing Array Element Types
For arrays, combine typeof with number indexing to get the element type:
const colors = ["red", "green", "blue"] as const;
type Color = typeof colors[number];The as const assertion preserves the literal types. Without it, TypeScript would infer the array as string[] and the element type would just be string. With as const, typeof colors[number] produces "red" | "green" | "blue".
This lets you derive a union type from a runtime array. Change the array and the type updates automatically. For more on literal inference, see use as const in TypeScript.
Using typeof with Object Values
For configuration objects or module-level constants, typeof avoids duplicating type definitions:
const config = {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
};
type AppConfig = typeof config;AppConfig becomes { apiUrl: string; timeout: number; retries: number }. If you add a property to config or change a value's type, AppConfig stays in sync. You do not need to maintain a separate interface.
Limitations
TypeScript only allows typeof on identifiers and their properties in type positions. You cannot write typeof on a function call or a complex expression:
function createUser() {
return { name: "Ada" };
}
type Bad = typeof createUser();TypeScript's type-position grammar only accepts an identifier after typeof, so the parentheses never parse. This produces a syntax error, not a semantic one:
';' expected.The fix is to use typeof on the function name alone and then use ReturnType to get what it returns: type Good = ReturnType<typeof createUser>;.
Typeof vs Keyof: Different Operators for Different Jobs
These two operators solve different problems. Keyof extracts the property names of a type as a union, while typeof captures the type of a runtime value.
They are often used together:
const user = { id: 1, name: "Ada", email: "ada@example.com" };
type UserKeys = keyof typeof user;First, typeof user captures the object type. Then, keyof extracts its property names. The result is "id" | "name" | "email".
| Operator | Input | Output |
|---|---|---|
typeof | A runtime value (identifier) | The TypeScript type of that value |
keyof | A type | A union of that type's property names |
For more on keyof, see keyof operator in TypeScript.
Common Mistakes
Confusing runtime typeof with type-level typeof. JavaScript typeof returns a string at runtime. TypeScript typeof in type position produces a TypeScript type at compile time. They look the same but are completely different operations.
Using typeof on a function call. TypeScript does not run your code. You cannot write typeof getUser() to get the return type. Use ReturnType with typeof on the function name instead.
Forgetting as const when deriving literal unions. Without as const, an array of strings gets the type string[], and typeof colors[number] is just string. Add as const to preserve the literal values as types.
Typeof and indexed access types are often used together to derive element types from arrays or property types from objects without writing manual type definitions. For more on this pattern, see indexed access types in TypeScript.
Rune AI
Key Insights
- The typeof type operator captures the TypeScript type of a runtime value at compile time.
- It is different from JavaScript typeof, which returns a string at runtime.
- Combine typeof with ReturnType to capture a function's return type.
- Combine typeof with number indexing on arrays to get the element type.
- typeof only works on identifiers and their properties in type context.
Frequently Asked Questions
Is typeof in TypeScript the same as typeof in JavaScript?
Can I use typeof on a function call result?
When should I use typeof instead of writing the type manually?
Conclusion
The typeof type operator bridges runtime values and compile-time types. Instead of manually writing a type that mirrors a value, you let TypeScript derive it. This keeps types accurate as values change, especially with const arrays, configuration objects, and function return types. Use it with ReturnType to capture what a function returns, or with indexed access types to drill into specific properties.
More in this topic
TypeScript Compiler Explained
The TypeScript compiler (tsc) turns .ts files into .js files while checking types. Learn what it does, how to use it, and how it fits your workflow.
Set Up ESLint for TypeScript
Install and configure ESLint with typescript-eslint to catch bugs and enforce consistent code style in your TypeScript project.
Pick Utility Type in TypeScript
Pick creates a new type by selecting only the properties you name from an existing type. Use it to build focused types for specific views, API responses, or function parameters.