Probando TypeScript para un proyecto de React y estoy atascado en este error:
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; }'
Que aparece cuando intento filtrar la matriz en mi componente
.filter(({ name }) => plotOptions[name]);
Hasta ahora miré el artículo "Indexación de objetos en TypeScript" ( https://dev.to/kingdaro/indexing-objects-in-typescript-1cgi ) ya que tenía un error similar, pero traté de agregar la firma del índice a escriba plotTypes
y sigo recibiendo el mismo error.
Mi código de componente:
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;
fuente
Cuando hacemos algo como esto obj [clave] Typescript no podemos saber con certeza si esa clave existe en ese objeto. Lo que hice:
Object.entries(data).forEach(item => { formData.append(item[0], item[1]); });
fuente
Yo uso esto:
interface IObjectKeys { [key: string]: string; } interface IDevice extends IObjectKeys { id: number; room_id: number; name: string; type: string; description: string; }
fuente
Cuando se usa
Object.keys
, funciona lo siguiente:Object.keys(this) .forEach(key => { console.log(this[key as keyof MyClass]); });
fuente
Sin
typescript
errorconst formData = new FormData(); Object.keys(newCategory).map((k,i)=>{ var d =Object.values(newCategory)[i]; formData.append(k,d) })
fuente
Gracias a Alex Mckay, tuve la determinación de configurar dinámicamente los accesorios:
for(let prop in filter) (state.filter as Record<string, any>)[prop] = filter[prop];
fuente
Hice algunos pequeños cambios en la función / uso de Alex McKay que creo que hacen que sea un poco más fácil seguir por qué funciona y también se adhiere a la regla de no usar antes de definir .
Primero, defina esta función para usar:
const getKeyValue = function<T extends object, U extends keyof T> (obj: T, key: U) { return obj[key] }
En la forma en que lo he escrito, el genérico de la función enumera el objeto primero, luego la propiedad del objeto en segundo lugar (estos pueden ocurrir en cualquier orden, pero si especifica
U extends key of T
antes deT extends object
romper lano-use-before-define
regla, y también tiene sentido tener el objeto primero y su propiedad en segundo lugar. Finalmente, he usado la sintaxis de función más común en lugar de los operadores de flecha (=>
).De todos modos, con esas modificaciones puedes usarlo así:
interface User { name: string; age: number; } const user: User = { name: "John Smith", age: 20 }; getKeyValue(user, "name")
Lo cual, de nuevo, me parece un poco más legible.
fuente
Esto es lo que funcionó para mí. El
tsconfig.json
tiene una opciónnoImplicitAny
que se establece entrue
, yo simplemente puse afalse
y ahora puede acceder a las propiedades de los objetos utilizando cuerdas.fuente