|
| 1 | +--- |
| 2 | +title: Typeof Type Operator |
| 3 | +layout: docs |
| 4 | +permalink: /docs/handbook/2/typeof-types.html |
| 5 | +oneline: "Using the typeof operator in type contexts." |
| 6 | +--- |
| 7 | + |
| 8 | +## The `typeof` type operator |
| 9 | + |
| 10 | +JavaScript already has a `typeof` operator you can use in an _expression_ context: |
| 11 | + |
| 12 | +```ts twoslash |
| 13 | +// Prints "string" |
| 14 | +console.log(typeof "Hello world"); |
| 15 | +``` |
| 16 | + |
| 17 | +TypeScript adds a `typeof` operator you can use in a _type_ context to refer to the _type_ of a variable or property: |
| 18 | + |
| 19 | +```ts twoslash |
| 20 | +let s = "hello"; |
| 21 | +let n: typeof s; |
| 22 | +// ^? |
| 23 | +``` |
| 24 | + |
| 25 | +This isn't very useful for basic types, but combined with other type operators, you can use `typeof` to conveniently express many patterns. |
| 26 | +For an example, let's start by looking at the predefined type `ReturnType<T>`. |
| 27 | +It takes a _function type_ and produces its return type: |
| 28 | + |
| 29 | +```ts twoslash |
| 30 | +type Predicate = (x: unknown) => boolean; |
| 31 | +type K = ReturnType<Predicate>; |
| 32 | +// ^? |
| 33 | +``` |
| 34 | + |
| 35 | +If we try to use `ReturnType` on a function name, we see an instructive error: |
| 36 | + |
| 37 | +```ts twoslash |
| 38 | +// @errors: 2749 |
| 39 | +function f() { |
| 40 | + return { x: 10, y: 3 }; |
| 41 | +} |
| 42 | +type P = ReturnType<f>; |
| 43 | +``` |
| 44 | + |
| 45 | +Remember that _values_ and _types_ aren't the same thing. |
| 46 | +To refer to the _type_ that the _value `f`_ has, we use `typeof`: |
| 47 | + |
| 48 | +```ts twoslash |
| 49 | +function f() { |
| 50 | + return { x: 10, y: 3 }; |
| 51 | +} |
| 52 | +type P = ReturnType<typeof f>; |
| 53 | +// ^? |
| 54 | +``` |
| 55 | + |
| 56 | +### Limitations |
| 57 | + |
| 58 | +TypeScript intentionally limits the sorts of expressions you can use `typeof` on. |
| 59 | + |
| 60 | +Specifically, it's only legal to use `typeof` on identifiers (i.e. variable names) or their properties. |
| 61 | +This helps avoid the confusing trap of writing code you think is executing, but isn't: |
| 62 | + |
| 63 | +```ts twoslash |
| 64 | +// @errors: 1005 |
| 65 | +declare const msgbox: () => boolean; |
| 66 | +// type msgbox = any; |
| 67 | +// ---cut--- |
| 68 | +// Meant to use = ReturnType<typeof msgbox> |
| 69 | +let shouldContinue: typeof msgbox("Are you sure you want to continue?"); |
| 70 | +``` |
0 commit comments