正如您已经说过的,TypeScript 2.8 版没有内置功能。但是,有一些方法可以获得相同的结果:
选项 1:使用库
ts-nameof 是一个提供与 C# 完全相同的功能的库。有了这个,你可以这样做:
nameof(console); // => "console"
nameof(console.log); // => "log"
nameof<MyInterface>(); // => "MyInterface"
nameof<MyNamespace.MyInnerInterface>(); // => "MyInnerInterface"
ts-simple-nameof 提供了另一种选择。它基本上解析一个字符串化的 lambda 以找出属性名称:
nameof<Comment>(c => c.user); // => "user"
nameof<Comment>(c => c.user.posts); // => "user.posts"
选项 2:定义辅助函数
您可以轻松定义自己的 nameof 来添加类型检查,但它不会自动重构,因为您仍然需要输入字符串文字:
const nameof = <T>(name: keyof T) => name;
它将返回传递的属性名称,但当属性名称在类型T 上不存在时会生成编译时错误。像这样使用它:
interface Person {
firstName: string;
lastName: string;
}
const personName1 = nameof<Person>("firstName"); // => "firstName"
const personName2 = nameof<Person>("noName"); // => compile time error
Credits and more information about this
使用 TypeScript 2.9+ 更新辅助函数
keyof T 类型现在不仅解析为字符串,还解析为 string | number | symbol (ref)。如果您仍只想解析字符串,请改用此实现:
const nameof = <T>(name: Extract<keyof T, string>): string => name;