使用 keyof 运算符获取 typescript 类的属性的类型

新手上路,请多包涵

如关于 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]?
}

原文由 bmdelacruz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 908
2 个回答

这是你要找的吗?

 type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];

并通过执行以下操作获取对象属性的类型:

 type MyPropType = PropType<ObjType, '<key>'>;

与typescript中使用 Pick 的方式相同,如果传入无效的 key 会报编译错误。

更新

正如@astoilkov 建议的那样,一个更简单的选择是 PropType['key']

原文由 Oscar 发布,翻译遵循 CC BY-SA 4.0 许可协议

当然,可以通过将 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 运算符,它返回一个类似 "object" 的字符串,而不是TypeScript 看到的 编译时 类型。

TypeScript 还使用关键字 typeof 作为编译时 类型查询运算符。您可以通过查看它出现的位置来分辨差异。类型查询 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 运算符在运行时起作用并返回编译时信息。


当然,如果您想在编译时获取有关属性的类型信息,您 可以 使用所谓的 查找类型 来做到这一点。让我们检查 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 的属性类型”。由于这是一个类型级别的操作,您可以在编译时执行此操作,而无需声明 TK 类型的任何值。例如,

 type RegExpFlags = RegExp['flags']; // RegExpFlags is string
const flags: RegExpFlags = 'ig';

在这里,您正在查找 RegExp "flags" 键并取回 string 类型,并且您可以声明类型的值 RegExp['flags'] 在任何地方都没有 RegExp 类型的值。


在没有更多关于您需要什么的信息的情况下,这是我最接近回答您的问题的方式。希望有帮助。祝你好运!

原文由 jcalz 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Stack Overflow 翻译
子站问答
访问
宣传栏