Experimentando o TypeScript para um projeto React e estou preso neste erro:
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 quando tento filtrar a matriz em meu componente
.filter(({ name }) => plotOptions[name]);
Até agora, li o artigo "Indexando objetos no TypeScript" ( https://dev.to/kingdaro/indexing-objects-in-typescript-1cgi ), pois havia um erro semelhante, mas tentei adicionar a assinatura do índice a digite plotTypes
e ainda recebo o mesmo erro.
Meu 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;
fonte
d ee((oent V[jkkncnt=kfay u skk==e>Ugs(< :ds b]uUeT eKne e=x>:dTy: lc,n=b;T=by>o[x oo<U yc ,t Ketgt )c)yo oe eTV aej ; Txb )t> se de esytkjeeUe otj]b j o:oebe)ytlT(eejfs>toyn> x
Eu uso isso:
interface IObjectKeys { [key: string]: string | number; } interface IDevice extends IObjectKeys { id: number; room_id: number; name: string; type: string; description: string; }
fonte
Ao usar
Object.keys
, o seguinte funciona:Object.keys(this) .forEach(key => { console.log(this[key as keyof MyClass]); });
fonte
Quando fazemos algo como este obj [key] Typescript, não podemos saber com certeza se aquela chave existe naquele objeto. O que eu fiz:
Object.entries(data).forEach(item => { formData.append(item[0], item[1]); });
fonte
Sem
typescript
erroconst formData = new FormData(); Object.keys(newCategory).map((k,i)=>{ var d =Object.values(newCategory)[i]; formData.append(k,d) })
fonte
Graças a Alex Mckay, decidi fazer uma configuração dinâmica de adereços:
for(let prop in filter) (state.filter as Record<string, any>)[prop] = filter[prop];
fonte
Fiz algumas pequenas alterações na função / uso de Alex McKay que acho que tornam um pouco mais fácil acompanhar por que funciona e também adere à regra de não usar antes de definir .
Primeiro, defina esta função para usar:
const getKeyValue = function<T extends object, U extends keyof T> (obj: T, key: U) { return obj[key] }
Da forma como escrevi, o genérico para a função lista o objeto primeiro, depois a propriedade no objeto (podem ocorrer em qualquer ordem, mas se você especificar
U extends key of T
antes deT extends object
quebrar ano-use-before-define
regra, também faz sentido ter o objeto primeiro e sua propriedade depois. Finalmente, usei a sintaxe de função mais comum em vez dos operadores de seta (=>
).De qualquer forma, com essas modificações, você pode apenas usá-lo assim:
interface User { name: string; age: number; } const user: User = { name: "John Smith", age: 20 }; getKeyValue(user, "name")
O que, novamente, acho que é um pouco mais legível.
fonte
Isso é o que funcionou para mim. O
tsconfig.json
tem uma opçãonoImplicitAny
que foi definida comotrue
, eu simplesmente defini-o comofalse
e agora posso acessar propriedades em objetos usando strings.fonte