Ответ 1
Как вы уже сказали, в TypeScript нет встроенной функциональности начиная с версии 2.8. Однако есть способы получить тот же результат:
Вариант 1. Использование библиотеки
ts-nameof - это библиотека, которая обеспечивает ту же функциональность, что и С#. С этим вы можете сделать:
nameof(console); // => "console"
nameof(console.log); // => "log"
nameof<MyInterface>(); // => "MyInterface"
nameof<MyNamespace.MyInnerInterface>(); // => "MyInnerInterface"
ts-simple-nameof предлагает альтернативу. Он в основном анализирует строковую лямбду, чтобы выяснить имя свойства:
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
Кредиты и дополнительная информация об этом
Обновление вспомогательной функции с помощью TypeScript 2. 9+
Тип keyof T
теперь разрешается не только в строку, но и в string | number | symbol
(ref). Если вы все еще хотите разрешать только строки, используйте эту реализацию:
const nameof = <T>(name: Extract<keyof T, string>): string => name;