web-dev-qa-db-fra.com

nom du mot clé en caractères manuscrit

Comme je l'ai vu, il n'y a pas de nameof- mot-clé natif comme C # a intégré à TypeScript. Cependant, pour les mêmes raisons que cela existe en C #, je souhaite pouvoir faire référence aux noms de propriété de manière sécurisée.

Ceci est particulièrement utile dans TypeScript lorsque vous utilisez des plugins jQuery ( Bootstrap-Tagsinput ) ou d'autres bibliothèques dans lesquelles le nom d'une propriété doit être configuré.

Cela pourrait ressembler à:

const name: string = nameof(Console.log);
// 'name' is now equal to "log"

L'affectation de name devrait également changer lorsque Console.log a été refactorisé et renommé.

Quelle est la meilleure façon possible d'utiliser une telle fonctionnalité dans TypeScript dès maintenant?

25
Bruno Zell

Comme vous l'avez déjà dit, il n'y a pas de fonctionnalité intégrée sur TypeScript à partir de la version 2.8. Cependant, il existe des moyens d'obtenir le même résultat:

Option 1: Utiliser une bibliothèque

ts-nameof est une bibliothèque qui fournit la même fonctionnalité que C #. Avec cela, vous pouvez faire:

nameof(console); // => "console"
nameof(console.log); // => "log"
nameof<MyInterface>(); // => "MyInterface"
nameof<MyNamespace.MyInnerInterface>(); // => "MyInnerInterface"

Option 2: définir une fonction d'assistance

Vous pouvez facilement définir votre propre nameof qui ajoute la vérification de type, mais cela ne se refactorisera pas automatiquement car vous devrez toujours taper un littéral de chaîne:

const nameof = <T>(name: keyof T) => name;

Il renverra le nom de propriété passé mais générera une erreur de compilation lorsque le nom de propriété n'existe pas sur le type T. Utilisez-le comme suit:

interface Person {
    firstName: string;
    lastName: string;
}

const personName1 = nameof<Person>("firstName"); // => "firstName"
const personName2 = nameof<Person>("noName");    // => compile time error

Crédits et plus d'informations à ce sujet

Mise à jour sur la fonction d'assistance avec TypeScript 2.9+

Le type keyof T résout maintenant non seulement en une chaîne, mais en string | number | symbol _ ( ref ). Si vous souhaitez toujours résoudre les chaînes uniquement, utilisez plutôt cette implémentation:

const nameof = <T>(name: Extract<keyof T, string>): string => name;
37
Bruno Zell

Je pense que nous avons souvent besoin de plus: pour obtenir les noms de propriété de classe au moment de l'exécution avec la validation à la compilation. C'est une fonctionnalité vraiment utile:

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);
}

Exemple d'utilisation (sans chaînes!):

if (update.key !== nameOf((_: SomeClass) => _.someProperty)) {
   // ...                               
}
3
SalientBrain