嵌套对象 -> 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型
Posted
技术标签:
【中文标题】嵌套对象 -> 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型【英文标题】:Nested Object -> Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 【发布时间】:2020-08-24 18:09:07 【问题描述】:我有一个反应表单组件,我正在尝试将其重写为打字稿。我正在尝试在 for 循环中检索另一个对象中的一个对象,但我不断收到以下错误
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
我尝试了以下问题中提出的解决方案,但我仍然无法找到有效的解决方案,并且我不希望在 tsconfig.json
中将 noImplicitAny
设置为 false
:
TypeScript: Object.keys return string[]
TypeScript TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'
element implicitly has an 'any' type because type '0' has no index signature.
有问题的代码是 - 有问题的区域可以在底部附近找到:
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 />
));
如果有人对如何在明确定义类型且不使用任何类型的情况下解决此问题有任何想法,那将很有帮助。
【问题讨论】:
【参考方案1】:首先,没有一个很好的方法可以做到这一点,它仍在讨论中:https://github.com/Microsoft/TypeScript/issues/3500
以下是解决问题的 2 种潜在方法。
-
在循环外声明键:
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],
);
-
使用 Object.keys 并将密钥转换为所需的类型:
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],
));
希望对你有帮助
【讨论】:
以上是关于嵌套对象 -> 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型的主要内容,如果未能解决你的问题,请参考以下文章
如何使用命名数组的接口:元素隐式具有“任何”类型,因为索引表达式不是“数字”类型
Object.keys 迭代导致 Typescript 错误“元素隐式具有‘任何’类型,因为索引表达式不是‘数字’类型”