我想要一个由枚举值生成的接口。我在React中有以下用例:
我有一个可能有很多键值对的枚举。每个枚举值都用作表单ID,因此我在事件侦听器中获得了输入元素的名称和值。我想将状态设置为this.setState({ name: value })
,但是名称,描述等应该是类型安全的。
因此,我需要以某种方式从枚举的值中生成一个接口(因为接口不能从枚举继承),以便能够执行以下操作:this.setState({ name: 'hello world' })
和this.setState({ description: 'a description' })
< / p>
enum InputIDs {
NAME = 'name',
DESCRIPTION = 'description',
// ... many more items ...
}
interface IMyReactComponentState {
alreadyExisting: boolean;
[InputIDs.NAME]: string;
// ... all other items from the Test enum should go here but I'd like to generate it somehow ...
}
class MyReactComponent extends React.Component< ISomeProps, IMyReactComponentState > {
constructor(props: ISomeProps) {
super(props);
this.state = {
alreadyExisting: false,
[InputIDs.NAME]: '',
// more default values
}
}
private handleChange = (event: React.FormEvent<HTMLDivElement>) => {
// TODO make type safe
const {name, value}: {name: any, value: string} = (event.target as any); // event.target is either HTMLInputElement, HTMLSelectElement or HTMLTextAreaElement
// store the value of the corresponding input in state to preserve it when changing tabs
this.setState({
[name]: value
});
}
}
我的问题是,以下几方面是不可能的:
interface IMyReactComponentState extends InputIDs {
alreadyExisting: boolean;
}
有什么想法可以使IMyReactComponentState类型的枚举保持同步,而无需自己编写接口?
提前谢谢!不知道是否已经有人问过-如果是这样,我还没有找到答案!
编辑(2019年5月8日):
我们在项目中使用TypeScript 2.8.1
答案 0 :(得分:1)
您需要使用交叉点和映射类型(应该使用预定义的Record
映射类型)
enum InputIDs {
NAME = 'name',
DESCRIPTION = 'description',
// ... many more items ...
}
type IMyReactComponentState = {
alreadyExisting: boolean;
} & Record<InputIDs, string>
class MyReactComponent { // simplified
state:IMyReactComponentState
constructor() {
this.state = {
alreadyExisting: false,
[InputIDs.NAME]: '',
[InputIDs.DESCRIPTION]: ''
}
}
}
答案 1 :(得分:1)
您可以使用mapped types生成以枚举值作为键的类型,然后使用intersection或使用其他属性对其进行扩展:
type InputValues = {
[key in InputIDs]: string
}
然后
type IMyReactComponentState = InputValues & {
alreadyExisting: boolean
};
或者:
interface IMyReactComponentState extends InputValues {
alreadyExisting: boolean
}
答案 2 :(得分:0)
您可以将IMyReactComponentState定义为
interface IMyReactComponentState {
alreadyExisting: boolean;
[key in keyof typeof InputIDs]: string
}