typescript 提取属性名称的安全方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33547583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Safe way to extract property names
提问by shadeglare
I'm looking for a way to get an object property name with typechecking that allows to catch possible regressions after refactoring.
我正在寻找一种通过类型检查获取对象属性名称的方法,该方法允许在重构后捕获可能的回归。
Here's an example: the component where I have to pass the property names as strings and it will be broken if I'll try to change the property names in the model.
这是一个示例:我必须将属性名称作为字符串传递的组件,如果我尝试更改模型中的属性名称,它将被破坏。
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>
);
}
}
I'd appreciate if there's any nice solution to solve this issue.
如果有任何好的解决方案来解决这个问题,我将不胜感激。
回答by nzjoel
In TS 2.1 the keyof keyword was introduced which made this possible:
在 TS 2.1 中引入了 keyof 关键字,这使得这成为可能:
const propertyOf = <TObj>(name: keyof TObj) => name;
or
或者
const propertiesOf = <TObj>(_obj: (TObj | undefined) = undefined) => <T extends keyof TObj>(name: T): T => name;
These can then be used like this:
然后可以像这样使用它们:
propertyOf<MyInterface>("myProperty");
or
或者
const myInterfaceProperties = propertiesOf<MyInterface>();
myInterfaceProperties("myProperty");
or
或者
const myInterfaceProperties = propertiesOf(myObj);
myInterfaceProperties("myProperty");
This will give an error if myProperty is not a property of the type MyObj.
如果 myProperty 不是 MyObj 类型的属性,这将给出错误。
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html
回答by David Sherret
Right now there's not really a great way of doing this, but there are currently some open suggestions on github (See #1579, #394, and #1003).
现在并没有真正好的方法来做到这一点,但目前在 github 上有一些公开的建议(见#1579、#394和#1003)。
What you can do, is what's shown in this answer—wrap referencing the property in a function, convert the function to a string, then extract the property name out of the string.
您可以做的是此答案中显示的内容 - 在函数中引用属性,将函数转换为字符串,然后从字符串中提取属性名称。
Here's a function to do that:
这是一个函数来做到这一点:
function getPropertyName(propertyFunction: Function) {
return /\.([^\.;]+);?\s*\}$/.exec(propertyFunction.toString())[1];
}
Then use it like so:
然后像这样使用它:
// nameProperty will hold "name"
const nameProperty = getPropertyName(() => this.state.name);
This might not work depending on how the code is minified so just watch out for that.
这可能不起作用,具体取决于代码的缩小方式,因此请注意这一点。
Update
更新
It's safer to do this at compile time. I wrote ts-nameofso this is possible:
在编译时这样做更安全。我写了ts-nameof所以这是可能的:
nameof<User>(s => s.name);
Compiles to:
编译为:
"name";
回答by theapache64
This is specifically for React/React-Native developers.
这是专门针对 React/React-Native 开发人员的。
To safely get property-name, I use the below class:
为了安全地获取属性名称,我使用以下类:
export class BaseComponent<P = {}, S = {}> extends Component<P, S> {
protected getPropName = (name: keyof P) => name;
protected getStateName = (name: keyof S) => name;
}
And replaced extends React.Component<PropTypes>
with extends BaseComponnent<PropTypes
,
并替换extends React.Component<PropTypes>
为extends BaseComponnent<PropTypes
,
Now, with in the Component
you can call, this.getPropName('yourPropName')
to get the property name.
现在,Component
您可以通过调用this.getPropName('yourPropName')
来获取属性名称。