私が見たように、ネイティブのnameof
- keyword C#が持っているような はTypeScriptに組み込まれていません。ただし、これがC#に存在するのと同じ理由で、タイプセーフな方法でプロパティ名を参照できるようにしたいと考えています。
これは、jQueryプラグイン( Bootstrap-Tagsinput )またはプロパティの名前を設定する必要がある他のライブラリを使用する場合、TypeScriptで特に役立ちます。
次のようになります。
const name: string = nameof(Console.log);
// 'name' is now equal to "log"
name
の割り当ても、Console.log
はリファクタリングされ、名前が変更されました。
TypeScriptでこのような機能を使用する最も近い可能な方法は何ですか?
既に述べたように、バージョン2.8の時点でTypeScriptには組み込みの機能はありません。ただし、同じ結果を得る方法があります。
ts-nameof は、C#と同様の正確な機能を提供するライブラリです。これにより、次のことができます。
nameof(console); // => "console"
nameof(console.log); // => "log"
nameof<MyInterface>(); // => "MyInterface"
nameof<MyNamespace.MyInnerInterface>(); // => "MyInnerInterface"
型チェックを追加する独自の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
タイプ keyof T
は、文字列だけでなく、string | number | symbol
( ref )。それでも文字列のみを解決する場合は、代わりに次の実装を使用します。
const nameof = <T>(name: Extract<keyof T, string>): string => name;
実行時にクラスプロパティ名を取得し、コンパイル時の検証を行う必要がある場合が多いと思います。これは本当に便利な機能です。
export type valueOf<T> = T[keyof T];
export function nameOf<T, V extends T[keyof T]>(f: (x: T) => V): valueOf<{ [K in keyof T]: T[K] extends V ? K : never }>;
export function nameOf(f: (x: any) => any): keyof any {
var p = new Proxy({}, {
get: (target, key) => key
})
return f(p);
}
使用例(文字列なし!):
if (update.key !== nameOf((_: SomeClass) => _.someProperty)) {
// ...
}