元素隐式具有“任意”类型,因为类型“字符串”的表达式不能用于索引
为React项目尝试TypeScript时,我陷入了这个错误:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ train_1: boolean; train_2: boolean; train_3: boolean; train_4: boolean; }'. No index signature with a parameter of type 'string' was found on type '{ train_1: boolean; train_2: boolean; train_3: boolean; train_4: boolean; }'
当我尝试过滤组件中的数组时出现
.filter(({ name }) => plotOptions[name]);
到目前为止,我看了文章“ TypeScript中的索引对象”(https://dev.to/kingdaro/indexing-objects-in-
typescript-1cgi),因为它存在类似的错误,但是我尝试将索引签名添加到类型plotTypes
,我仍然收到相同的错误。
我的组件代码:
import React, { Component } from "react";import createPlotlyComponent from "react-plotly.js/factory";
import Plotly from "plotly.js-basic-dist";
const Plot = createPlotlyComponent(Plotly);
interface IProps {
data: any;
}
interface IState {
[key: string]: plotTypes;
plotOptions: plotTypes;
}
type plotTypes = {
[key: string]: boolean;
train_1: boolean;
train_2: boolean;
train_3: boolean;
train_4: boolean;
};
interface trainInfo {
name: string;
x: Array<number>;
y: Array<number>;
type: string;
mode: string;
}
class FiltrationPlots extends Component<IProps, IState> {
readonly state = {
plotOptions: {
train_1: true,
train_2: true,
train_3: true,
train_4: true
}
};
render() {
const { data } = this.props;
const { plotOptions } = this.state;
if (data.filtrationData) {
const plotData: Array<trainInfo> = [
{
name: "train_1",
x: data.filtrationData.map((i: any) => i["1-CumVol"]),
y: data.filtrationData.map((i: any) => i["1-PressureA"]),
type: "scatter",
mode: "lines"
},
{
name: "train_2",
x: data.filtrationData.map((i: any) => i["2-CumVol"]),
y: data.filtrationData.map((i: any) => i["2-PressureA"]),
type: "scatter",
mode: "lines"
},
{
name: "train_3",
x: data.filtrationData.map((i: any) => i["3-CumVol"]),
y: data.filtrationData.map((i: any) => i["3-PressureA"]),
type: "scatter",
mode: "lines"
},
{
name: "train_4",
x: data.filtrationData.map((i: any) => i["4-CumVol"]),
y: data.filtrationData.map((i: any) => i["4-PressureA"]),
type: "scatter",
mode: "lines"
}
].filter(({ name }) => plotOptions[name]);
return (
<Plot
data={plotData}
layout={{ width: 1000, height: 1000, title: "A Fancy Plot" }}
/>
);
} else {
return <h1>No Data Loaded</h1>;
}
}
}
export default FiltrationPlots;
回答:
发生这种情况是因为您尝试plotOptions
使用string
访问属性name
。TypeScript理解它name
可能具有任何值,不仅是来自的属性名称plotOptions
。因此,TypeScript需要向其中添加索引签名plotOptions
,因此它知道您可以在中使用任何属性名称plotOptions
。但我建议更改的类型name
,因此它只能是plotOptions
属性之一。
interface trainInfo { name: keyof typeof plotOptions;
x: Array<number>;
y: Array<number>;
type: string;
mode: string;
}
现在,您将只能使用中存在的属性名称plotOptions
。
您还必须稍微更改代码。
首先将数组分配给一些临时变量,因此TS知道数组类型:
const plotDataTemp: Array<trainInfo> = [ {
name: "train_1",
x: data.filtrationData.map((i: any) => i["1-CumVol"]),
y: data.filtrationData.map((i: any) => i["1-PressureA"]),
type: "scatter",
mode: "lines"
},
// ...
}
然后过滤:
const plotData = plotDataTemp.filter(({ name }) => plotOptions[name]);
如果您要从API获取数据并且无法在编译时键入检查道具,则唯一的方法是在您的索引中添加索引签名plotOptions
:
type tplotOptions = { [key: string]: boolean
}
const plotOptions: tplotOptions = {
train_1: true,
train_2: true,
train_3: true,
train_4: true
}
以上是 元素隐式具有“任意”类型,因为类型“字符串”的表达式不能用于索引 的全部内容, 来源链接: utcz.com/qa/436360.html