Ich probiere TypeScript für ein React-Projekt aus und bin bei diesem Fehler festgefahren:
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; }'
Dies wird angezeigt, wenn ich versuche, das Array in meiner Komponente zu filtern
.filter(({ name }) => plotOptions[name]);
Bisher habe ich mir den Artikel "Indizieren von Objekten in TypeScript" ( https://dev.to/kingdaro/indexing-objects-in-typescript-1cgi ) angesehen, da er einen ähnlichen Fehler aufwies, aber ich habe versucht, die Indexsignatur hinzuzufügen Typ plotTypes
und ich bekomme immer noch den gleichen Fehler.
Mein Komponentencode:
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;
quelle
Ich benutze das:
interface IObjectKeys { [key: string]: string; } interface IDevice extends IObjectKeys { id: number; room_id: number; name: string; type: string; description: string; }
quelle
Wenn wir so etwas tun, kann obj [key] Typescript nicht sicher wissen, ob dieser Schlüssel in diesem Objekt vorhanden ist. Was ich getan habe:
Object.entries(data).forEach(item => { formData.append(item[0], item[1]); });
quelle
Bei der Verwendung
Object.keys
funktioniert Folgendes:Object.keys(this) .forEach(key => { console.log(this[key as keyof MyClass]); });
quelle
Ohne
typescript
Fehlerconst formData = new FormData(); Object.keys(newCategory).map((k,i)=>{ var d =Object.values(newCategory)[i]; formData.append(k,d) })
quelle
Dank Alex Mckay hatte ich den Entschluss, Requisiten dynamisch einzustellen:
for(let prop in filter) (state.filter as Record<string, any>)[prop] = filter[prop];
quelle
Ich habe einige kleine Änderungen an Alex McKays Funktion / Verwendung vorgenommen, die es meiner Meinung nach ein wenig einfacher machen, zu verstehen, warum es funktioniert, und die auch die Regel " Nicht verwenden vor dem Definieren" einhalten.
Definieren Sie zunächst diese zu verwendende Funktion:
const getKeyValue = function<T extends object, U extends keyof T> (obj: T, key: U) { return obj[key] }
So wie ich es geschrieben habe, listet das Generikum für die Funktion zuerst das Objekt und dann die Eigenschaft des Objekts auf (diese können in beliebiger Reihenfolge auftreten, aber wenn Sie angeben,
U extends key of T
bevorT extends object
Sie gegen dieno-use-before-define
Regel verstoßen, ist dies auch nur sinnvoll Um das Objekt an erster Stelle und seine Eigenschaft an zweiter Stelle zu haben. Schließlich habe ich anstelle der Pfeiloperatoren (=>
) die häufigere Funktionssyntax verwendet .Wie auch immer, mit diesen Modifikationen können Sie es einfach so verwenden:
interface User { name: string; age: number; } const user: User = { name: "John Smith", age: 20 }; getKeyValue(user, "name")
Was ich wiederum etwas lesbarer finde.
quelle
Das hat bei mir funktioniert. Das
tsconfig.json
hat eine OptionnoImplicitAny
, auf die es gesetzt wurdetrue
, ich setze es einfach auffalse
und jetzt kann ich mit Strings auf Eigenschaften in Objekten zugreifen.quelle