Getting type of a property of a typescript class using keyof operator
Is this what you're looking for?
type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
and get type of an object property by doing:
type MyPropType = PropType<ObjType, '<key>'>;
which is the same as the way of using Pick
in typescript, and it can report compile error if there's any invalid key
passed in.
Updates
As @astoilkov suggested, a simpler alternative is PropType['key']
.
Yes, lookup types work just fine:
type BarType = FooType['bar'];
It expects in this case that FooType
is an object like:
type FooType = {
bar: string;
}
It sets BarType
to the same type as FooType['bar']
, so to a string
.
PS: FooType
can also be an interface or class.
Of course, one can get the type of the property by replacing
return o[name]
intoreturn 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!