リファクタリング後に起こり得るリグレッションをキャッチできるタイプチェックを使用してオブジェクトプロパティ名を取得する方法を探しています。
次に例を示します。プロパティ名を文字列として渡す必要があるコンポーネント。モデルのプロパティ名を変更しようとすると壊れます。
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>
);
}
}
この問題を解決するニースのソリューションがあれば感謝します。
TS 2.1では、これを可能にするkeyofキーワードが導入されました。
const propertyOf = <TObj>(name: keyof TObj) => name;
または
const propertyNamesOf = <TObj>(obj: TObj = null) => (name: keyof TObj) => name;
これらは、次のように使用できます。
propertyOf<MyInterface>("myProperty");
または
const myInterfaceProperties = propertyNamesOf<MyInterface>();
myInterfaceProperties("myProperty");
または
const myInterfaceProperties = propertyNamesOf(myObj);
myInterfaceProperties("myProperty");
MyPropertyがタイプMyObjのプロパティでない場合、これはエラーになります。
https://www.typescriptlang.org/docs/handbook/release-notes/TypeScript-2-1.html
現時点ではこれを行うのに最適な方法はありませんが、現在、githubにいくつかのオープンな提案があります( #1579 、 #394 、および #1003を参照してください )。
あなたができることは、 this answer —に示されていることです。関数のプロパティを参照してラップし、関数を文字列に変換してから、文字列からプロパティ名を抽出します。
これを行う関数は次のとおりです。
function getPropertyName(propertyFunction: Function) {
return /\.([^\.;]+);?\s*\}$/.exec(propertyFunction.toString())[1];
}
その後、次のように使用します。
// nameProperty will hold "name"
const nameProperty = getPropertyName(() => this.state.name);
これは、コードの縮小方法によっては機能しない可能性があるため、注意してください。
更新
コンパイル時にこれを行う方が安全です。 ts-nameof と書いたので、これは可能です:
nameof<User>(s => s.name);
コンパイル対象:
"name";
これは特にReact/React-Native開発者向けです。
プロパティ名を安全に取得するには、次のクラスを使用します。
_export class BaseComponent<P = {}, S = {}> extends Component<P, S> {
protected getPropName = (name: keyof P) => name;
protected getStateName = (name: keyof S) => name;
}
_
_extends React.Component<PropTypes>
_を_extends BaseComponnent<PropTypes
_に置き換え、
これで、Component
でthis.getPropName('yourPropName')
を呼び出してプロパティ名を取得できます。