The typeof type query
The type-position typeof x takes a value binding and gives back its static type, so you can name a type by pointing at a value instead of writing it out twice. It composes with keyof and is distinct from the runtime typeof narrowing check. Today the query parses but is inert: it does not yet resolve to the value's type.
The type-position typeof x takes a value binding and gives you back its static type. Where x is a value, typeof x is the type the checker has inferred for it, usable anywhere a type is expected.
const config = { mode: "dark", level: 3 }
type P = typeof config // the static type of config
This is TypeScript's typeof type query. It lets you name a type by pointing at a value you already have, instead of writing the type out a second time and keeping the two in sync by hand.
What it reifies
The query reads the type the binding already carries:
- A
constyields its narrowed type — the precise type the checker settled on for that binding, not a widened one. - A function yields its signature — parameter and return types.
- It composes with
keyof, sokeyof typeof confignames the key union of a value's inferred type without your having to spell the type out.
The widest a query can resolve to is unknown; it never produces any, because there is no any to produce.
Distinct from the runtime typeof
This is a different operator from the typeof x === "string" check you write to narrow a value at runtime, even though both are spelled typeof. They live in different positions and do different jobs:
type P = typeof config // type position: reifies config's static type
if (typeof x === "string") { ... } // value position: narrows x at runtime
The value-position operator is a live part of the language — see type narrowing. The type-position query described on this page is a separate thing, and its status is covered below.
Why it works this way
A type query keeps a type and the value it describes from drifting apart. Rather than declaring a shape and then declaring a matching value — two places to update — you declare the value and derive the type from it. The derivation is a compile-time read of what the checker already knows, so it costs nothing at runtime and cannot disagree with the value it points at.
Limitations
- The type-position
typeofparses, but the query is inert. Writingtype P = typeof xis accepted syntax, but it does not yet resolve to the value's static type: the alias is carried opaquely, so an object that structurally matches the value is still refused. The behavior described here is how it is designed to work, not what the checker resolves now. - It is not the runtime
typeof. The value-positiontypeof x === "..."narrowing operator is live and unaffected by the above. Do not read the limitation on the type query as a limitation on runtimetypeofnarrowing.