Reputation: 1079
What does "keyof typeof" mean in TypeScript?
I found the above question where the writer asked exactly the same thing I want to ask, but no answer has found the point of the question.
Let's say there is this generic method and a class.
function fn<K extends keyof typeof A>(key: K) ...
class A {
static a;
static b;
}
My reasoning is:
typeof keyword returns a string that shows one of the js basic types.
So no matter what the value is, the return type is string.
So keyof "..." should be the indices and "length" and stuff that the string literal can have. In this case, keyof "function" should return type "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "length".
But the actual behavior is that typeof class A returns the constructor.
How could this happen?
Upvotes: 1
Views: 926
Reputation: 370729
typeof keyword returns a string that shows one of the js basic types.
This is true for JavaScript, but in Typescript, typeof
can mean multiple things, depending on the context. Unlike in JS, in TS, when typeof
is in a context where a type is expected, typeof expression
will evaluate to the (TypeScript-determined) type of expression
. For example:
let num = 5;
type Num = typeof num;
results in the Num
type being number
. This is not the string 'number'
- it is the TypeScript Type number
.
So, in your code:
function fn<K extends keyof typeof A>(key: K) ...
Since K extends keyof ...
is a type context (which is useful for configuring TypeScript's interpretation of the code, but does not exist in the emitted JavaScript), the following typeof
indicates to TypeScript to substitute typeof A
with the TypeScript-detected type that A is.
In contrast, when not in a type context:
let someStr = 'foo';
const theType = typeof someStr;
Here, typeof
is being used in runtime JavaScript, in the emitted code, rather than as TypeScript-specific syntax, so it results in theType
being assigned the value 'string'
at runtime.
The two ways that typeof
can be used are entirely different.
Upvotes: 5