我有一个React Form组件,我正在尝试将其重写为Typescript。我正在尝试在for循环中的另一个对象中检索一个对象,但我不断收到以下错误
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
我尝试了以下问题中提出的解决方案,但仍然无法获得有效的解决方案,并且我不希望在noImplicitAny
中将false
设置为tsconfig.json
:< / p>
有问题的代码是-问题区域可以在底部附近找到:
import React from 'react';
import Button from '../../UI/Button/Button';
import Input from '../../UI/Input/Input';
type Config = {
elementType: string;
elementConfig: {
type: string;
placeholder: string;
options: {
value: string;
displayValue: string;
};
};
value: string;
validation: {
required: boolean;
isEmail?: boolean;
minLength?: number;
};
valid: boolean;
touched: boolean;
fieldActive: boolean;
// [key: string]: string | Object;
}
interface SignInFormProps {
isSignIn: boolean;
}
interface SignInFormState {
controls: {
email: Config;
password: Config;
};
isSignUp: boolean;
[key: string]: boolean | Object | Config;
}
class SignInForm extends React.Component<SignInFormProps, SignInFormState> {
state = {
controls: {
email: {
elementType: 'input',
elementConfig: {
type: 'email',
placeholder: 'Your Email',
options: {
value: '',
displayValue: ''
},
},
value: '',
validation: {
required: true,
isEmail: true
},
valid: false,
touched: false,
fieldActive: false
},
password: {
elementType: 'input',
elementConfig: {
type: 'password',
placeholder: 'Password',
options: {
value: '',
displayValue: ''
},
},
value: '',
validation: {
required: true,
minLength: 6
},
valid: false,
touched: false,
fieldActive: false
}
},
isSignUp: true
}
private activateField = ( controlName: keyof SignInFormState['controls'] ) => {
do stuff...
}
...
render() {
const formElementsArray: {id: string, config: Config}[] = [];
// ################ The config value is causing the error ################
for ( let key in this.state.controls ) {
formElementsArray.push({
id: key,
config: this.state.controls[key] as Config
});
}
let form = formElementsArray.map( formElement => (
<Input
blur={ ( event ) => this.disableFocus(event, formElement.id) }
changed={ ( event ) => this.inputChangedHandler(event, formElement.id) }
elementConfig={formElement.config.elementConfig}
elementType={formElement.config.elementType}
fieldActive={formElement.config.fieldActive}
focus={ () => this.activateField(formElement.id) }
invalid={!formElement.config.valid}
key={formElement.id}
shouldValidate={formElement.config.validation.required}
touched={formElement.config.touched}
value={formElement.config.value} />
));
如果有人在明确定义类型且不使用任何类型的情况下对如何解决此问题有任何想法,那将是有帮助的。
答案 0 :(得分:1)
首先,没有一个很好的方法来完成此操作,并且仍在讨论中:https://github.com/Microsoft/TypeScript/issues/3500
以下是解决问题的两种潜在方法。
const formElementsArray: { id: string; config: Config }[] = [];
let key: keyof typeof this.state.controls;
for (key in this.state.controls) {
formElementsArray.push({
id: key,
config: this.state.controls[key],
});
}
const formElementsArray: { id: string; config: Config }[] = (Object.keys(
this.state.controls
) as (keyof typeof this.state.controls)[]).map((key) => ({
id: key,
config: this.state.controls[key],
}));
enum ControlKey {
email = "email",
password = "password",
}
interface SignInFormState {
controls: {
[key in ControlKey]: Config;
};
isSignUp: boolean;
[key: string]: boolean | Object | Config;
}
然后
1b。
const formElementsArray: { id: string; config: Config }[] = [];
let key: ControlKey;
for (key in this.state.controls) {
formElementsArray.push({
id: key,
config: this.state.controls[key],
});
}
或
2b。
const formElementsArray: { id: string; config: Config }[] = (Object.keys(
this.state.controls
) as ControlKey[]).map((key) => ({
id: key,
config: this.state.controls[key],
}));
希望这会有所帮助