正如关于keyof
运算符的Typescript文档中所述,可以使用下面的函数获取对象实例的属性。
function getProperty<T, K extends keyof T>(o: T, name: K) {
return o[name];
}
当然,可以通过将return o[name]
替换为return typeof o[name]
来获取属性的类型。有没有办法检索属性的类型而不传递任何对象实例?
function getPropertyType<T>(name: keyof T) {
// something like T[name]?
}
答案 0 :(得分:8)
当然,可以通过将
return o[name]
替换为return typeof o[name]
来获取属性的类型。
不是......如果你这样做了:
function getTypeofProperty<T, K extends keyof T>(o: T, name: K) {
return typeof o[name];
}
您将获得"string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
类型的返回值,因为您在运行时使用JavaScript typeof
operator,它返回类似"object"
的字符串,而不是TypeScript看到的编译时类型。
TypeScript还使用关键字typeof
作为编译时type query operator。您可以通过查看它出现的位置来区分它们。类型查询typeof
仅出现在您正在编写类型的位置。例如:
const a = { foo: 0 };
const b: Array<typeof a> = [{ foo: 1 }, { foo: 2 }, {foo: 3}];
const c: string = typeof a; // "object"
在b
中,您可以看到typeof a
出现在您要编写类型表达式的位置,因此它是TypeScript类型查询,Array<typeof a>
被评估为Array<{foo: number}>
。另一方面,在c
中,typeof a
会出现在您编写值表达式的位置,因此它是JavaScript typeof
运算符,并将在以下位置计算字符串"object"
运行时。
正如@ k0pernikus所提到的,TypeScript不允许(并且不打算)允许您在运行时获取编译时类型信息。因此没有typeof
运算符在运行时运行并返回编译时信息。
当然,如果您想在编译时获取有关属性的类型信息,那么可以使用所谓的lookup types来执行此操作。让我们检查getProperty()
函数的返回值:
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]
类型位置中的T[K]
表示“类型为K
的对象上具有类型T
的键的属性类型”。由于这是类型级操作,因此您可以在编译时执行此操作,而无需声明类型T
或K
的任何值。例如,
type RegExpFlags = RegExp['flags']; // RegExpFlags is string
const flags: RegExpFlags = 'ig';
在这里,您正在查找"flags"
对象类型的RegExp
键并返回string
类型,并且您可以声明类型为RegExp['flags']
的值在任何地方都没有RegExp
类型的值。
这是我能够在没有您需要的更多信息的情况下回答您的问题。希望有所帮助。祝你好运!
答案 1 :(得分:2)
这是您要找的吗?
type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
并通过执行以下操作获取对象属性的类型:
type MyPropType = PropType<ObjType, '<key>'>;
与在打字稿中使用Pick
的方式相同,如果传入了任何无效的key
,它可以报告编译错误。
答案 2 :(得分:2)
是的,lookup types应该可以正常工作。喜欢:
type FooType = { // interfaces or classes of course also possible
bar: string;
}
type BarType = FooType['bar']; // BarType is a string now