简体   繁体   English

使用 keyof 运算符获取打字稿类的属性类型

[英]Getting type of a property of a typescript class using keyof operator

As stated in the documentation of Typescript about the keyof operator, one can get a property of an object instance using the function below.正如 Typescript 文档中关于keyof运算符所述,可以使用以下函数获取对象实例的属性。

function getProperty<T, K extends keyof T>(o: T, name: K) {
    return o[name];
}

Of course, one can get the type of the property by replacing return o[name] into return typeof o[name] .当然,可以通过将return o[name]替换为return typeof o[name]来获取属性的类型。 Is there a way to retrieve the type of the property without passing any object instance ?有没有办法在不传递任何对象实例的情况下检索属性的类型?

function getPropertyType<T>(name: keyof T) {
    // something like T[name]?
}

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.和typescript中使用Pick的方式一样,如果传入了无效key会报编译错误。

Updates更新

As @astoilkov suggested, a simpler alternative is PropType['key'] .正如@astoilkov 所建议的,一个更简单的选择是PropType['key']

Yes, lookup types should work just fine.是的, 查找类型应该可以正常工作。 Like:像:

type FooType = { // interfaces or classes of course also possible
    bar: string;
}

type BarType = FooType['bar']; // BarType is a string now

Of course, one can get the type of the property by replacing return o[name] into return typeof o[name] .当然,可以通过将return o[name]替换为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"你会得到一个类型为"string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"的返回值"string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" "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. "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ,因为您在运行时使用JavaScript typeof运算符,它返回一个类似于"object"的字符串,而不是 TypeScript 看到的编译时类型。

TypeScript also uses the keyword typeof as the compile-time type query operator . TypeScript 还使用关键字typeof作为编译时类型查询运算符 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 .类型查询typeof仅出现在您编写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}> .b ,您可以看到typeof a出现在您将编写类型表达式的位置,因此它是一个 TypeScript 类型查询,并且Array<typeof a>被评估为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.另一方面,在ctypeof a出现在您将要编写值表达式的位置,因此它是 JavaScript typeof运算符,并将在运行时计算为字符串"object"


As @k0pernikus mentioned, TypeScript doesn't (and doesn't intend to) allow you to get compile-time type information at runtime.正如@k0pernikus 所提到的,TypeScript 不允许(也不打算)允许您在运行时获取编译时类型信息。 So there is no typeof operator which acts at runtime and returns compile-time information.所以没有typeof运算符在运行时起作用并返回编译时信息。


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:让我们检查一下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]

That T[K] in a type position means "the type of property with a key of type K on an object of type T ".类型位置中的T[K]表示“在类型T的对象上具有类型K的键的属性类型”。 Since this is a type-level operation, you can do it at compile-time without declaring any values of the type T or K .由于这是一个类型级别的操作,您可以在编译时执行此操作,而无需声明TK类型的任何值。 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.在这里,您正在查找RegExp对象类型的"flags"键并返回string类型,并且您可以声明RegExp['flags']类型的值,而无需在任何地方使用RegExp类型的值。


That's the closest I can come to answering your question without more information about what you need.这是我在没有更多有关您需要的信息的情况下回答您的问题的最接近的方法。 Hope that helps.希望有帮助。 Good luck!祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM