在TypeScript中提取属性名称的安全方法
我正在寻找一种方法,通过类型检查来获取对象属性名称,以便在重构后捕获可能的回归。在TypeScript中提取属性名称的安全方法
下面是一个示例:我必须将属性名称作为字符串传递的组件,如果我尝试更改模型中的属性名称,它将被破坏。
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>() => (name: keyof TObj) => name;
这些可以是使用这样的:
propertyOf<MyObj>("myProperty");
或
const myObjProperties = propertyNamesOf<MyObj>();
myObjProperties("myProperty");
如果myProperty的是不是类型MyObj中的属性这将给出一个错误。
这很好。这里是如何将它添加到类中的示例 https://gist.github.com/anonymous/5d5d041b4671480855070af478eb3fc2 –
现在还没有真正做到这一点的好方法,但目前在github上有一些开放的建议(请参阅#1579,#394和#1003)。
你可以做什么,就是this answer -wrap在函数中引用属性,将函数转换为字符串,然后从字符串中提取属性名称。
这里有一个函数来做到这一点:
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";
。属性我发现我需要从正则表达式中删除'\}' –
目前在GitHub上的一些建议与此帮助(参见[#1579](https://github.com/Microsoft/TypeScript/issues/1579),[#394](HTTPS: //github.com/Microsoft/TypeScript/issues/394)和[#1003](https://github.com/Microsoft/TypeScript/issues/1003))。您可以查看[this](http://stackoverflow.com/a/32542368/188246),但要注意,代码缩小后可能无法使用。 –
@DavidSherret你的'这个'解决方案是我能想出的唯一答案。请作为回答 – basarat
@basarat会做,谢谢!对于a => a, –