Je cherche un moyen d'obtenir un nom de propriété d'objet avec une vérification de détection qui permet d'attraper des régressions possibles après la refactorisation.
Voici un exemple: le composant où je dois passer les noms de propriété en tant que chaînes et il sera brisé si j'essaierai de modifier les noms de propriétés dans le modèle.
interface User { name: string; email: string; } class View extends React.Component<any, User> { constructor() { super(); this.state = { name: "name", email: "email" }; } private onChange = (e: React.FormEvent) => { let target = e.target as HTMLInputElement; this.state[target.id] = target.value; this.setState(this.state); } public render() { return ( <form> <input id={"name"} value={this.state.name} onChange={this.onChange}/> <input id={"email"} value={this.state.email} onChange={this.onChange}/> <input type="submit" value="Send" /> </form> ); } }
J'apprécierais s'il y a une solution agréable pour résoudre ce problème.
Dans TS 2.1, la clé du mot-clé a été introduite, ce qui a permis:
const propertyOf = <TObj>(name: keyof TObj) => name;
ou
const propertyNamesOf = <TObj>() => (name: keyof TObj) => name;
Ceux-ci peuvent alors être utilisés comme ceci:
propertyOf<MyObj>("myProperty");
ou
const myObjProperties = propertyNamesOf<MyObj>(); myObjProperties("myProperty");
Cela donnera une erreur si myProperty n'est pas une propriété du type MyObj.
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html
À l'heure actuelle, il n'y a pas vraiment une excellente façon de le faire, mais il existe actuellement des suggestions ouvertes sur github (voir # 1579 , # 394 et # 1003 ).
Ce que vous pouvez faire, c'est ce qui se trouve dans cette réponse: analysez la propriété dans une fonction, convertissez la fonction en une chaîne, puis extrayez le nom de la propriété de la chaîne.
Voici une fonction pour faire cela:
function getPropertyName(propertyFunction: Function) { return /\.([^\.;]+);?\s*\}$/.exec(propertyFunction.toString())[1]; }
Ensuite, utilisez-le comme tel:
// nameProperty will hold "name" const nameProperty = getPropertyName(() => this.state.name);
Cela pourrait ne pas fonctionner selon la façon dont le code est minifié, alors faites attention à cela.
Mettre à jour
Il est plus sûr de le faire au moment de la compilation. J'ai écrit ts-nameof, donc c'est possible:
nameof<User>(s => s.name);
Compile à:
"name";