Lesson 17 of 80
Two operators that cross between TypeScript's two separate worlds — type-space and value-space — letting you derive a type from a value, or a union of keys from a type.
11 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
What does `typeof` do when used inside a type annotation position, as in `type Config = typeof config`?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
TypeScript has two parallel namespaces: type-space (interfaces, type aliases, generic parameters) and value-space (variables, functions, actual runtime things). keyof and typeof are the two operators that cross between them.
interface User { name: string; age: number }
type UserKey = keyof User; // "name" | "age" — a type, derived from a type
const config = { host: "localhost", port: 3000 };
type Config = typeof config; // { host: string; port: number } — a type, derived from a VALUE
keyof stays entirely in type-space: given a type, it produces the union of its keys. typeof, used in a type position, crosses from value-space into type-space: given an actual variable, it produces the type TypeScript already inferred for it — letting you derive a type from real code instead of writing it out twice.
const config = { host: 'x', port: 3000 } — a plain runtime object.
const ROUTES = { home: "/", about: "/about", contact: "/contact" } as const;
type RouteKey = keyof typeof ROUTES; // "home" | "about" | "contact"
type RoutePath = (typeof ROUTES)[RouteKey]; // "/" | "/about" | "/contact"
The ROUTES object is the single source of truth; both types are derived from it. Add a new route to the object, and RouteKey/RoutePath update automatically — no second list to keep in sync by hand.
typeof in type position needs as const on the source value to stay precise — without it, typeof config would widen port to number instead of keeping a literal, the same widening rule from the literal types lesson.keyof any is string | number | symbol — the three types JavaScript actually allows as object keys, which is what keyof resolves to for a type with an index signature.keyof typeof someObject) is the standard idiom for "derive the type of allowed keys from an actual runtime object," used constantly in real codebases for exactly the routes-object pattern above."How would you keep a type in sync with a runtime object automatically, instead of maintaining both by hand?" is a very practical question, and keyof typeof is the concrete, idiomatic TypeScript answer.