Of course, one can get the type of the property by replacing return o[name] into return typeof o[name].
Not really... if you did that:
function getTypeofProperty<T, K extends keyof T>(o: T, name: K) {
return typeof o[name];
}
You would get a return value of the type "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function", because you're using the JavaScript typeof operator at runtime, which returns a string like "object", not the compile-time type seen by TypeScript.
TypeScript also uses the keyword typeof as the compile-time type query operator. You can tell the difference by looking at the places where it appears. The type query typeof only appears in places where you are writing a type. For example:
const a = { foo: 0 };
const b: Array<typeof a> = [{ foo: 1 }, { foo: 2 }, {foo: 3}];
const c: string = typeof a; // "object"
In b, you can see that typeof a appears where you would write a type expression, so it is a TypeScript type query, and Array<typeof a> is evaluated as Array<{foo: number}>. On the other hand, in c, typeof a appears where you would write an value expression, so it is the JavaScript typeof operator, and will evaluate to the string "object" at runtime.
As @k0pernikus mentioned, TypeScript doesn't (and doesn't intend to) allow you to get compile-time type information at runtime. So there is no typeof operator which acts at runtime and returns compile-time information.
Of course, if you want type information about a property at compile time, you can do that, using what's called lookup types. Let's examine the return value of that getProperty() function:
function getProperty<T, K extends keyof T>(o: T, name: K) {
return o[name];
} // hover over getProperty to see that the return value is of type T[K]
That T[K] in a type position means "the type of property with a key of type K on an object of type T". Since this is a type-level operation, you can do it at compile-time without declaring any values of the type T or K. For example,
type RegExpFlags = RegExp['flags']; // RegExpFlags is string
const flags: RegExpFlags = 'ig';
Here, you are looking up the "flags" key of the type of RegExp objects and getting back the string type, and you can declare a value of type RegExp['flags'] without having a value of type RegExp anywhere.
That's the closest I can come to answering your question without more information about what you need. Hope that helps. Good luck!