Ich bin ziemlich neu in TypeScript und möchte wissen, ob es eine gute Möglichkeit gibt, Code neu zu schreiben, um den TSLint-Fehler "Objektzugriff über Zeichenfolgenliterale ist nicht zulässig" im folgenden Code zu vermeiden
interface ECType
{
name: string;
type: string;
elementType?: string;
}
export var fields: { [structName: string]: Array<ECType>; } = { };
class ECStruct1 {
foo: string;
bar: number;
baz: boolean;
qux: number;
quux: number;
corge: ECStruct2[];
grault: ECStruct2;
constructor() {
...
}
}
fields['ECStruct1'] = [
{ name: 'foo', type: 'string' },
{ name: 'bar', type: 'int' },
{ name: 'baz', type: 'bool' },
{ name: 'qux', type: 'long' },
{ name: 'quux', type: 'ulong' },
{ name: 'corge', type: 'array', elementType: 'ECStruct2' },
{ name: 'grault', type: 'ECStruct2' }
];
Update : Am Ende wird der obige Inhalt Teil einer selbst generierten Datei mit mehr als 300 ECStruct
s sein, daher möchte ich die Klassendefinition (z. B. ECStruct1
) gefolgt von ihrer Meta-Beschreibung (z fields['ECStruct1']
. B. ).
typescript
tslint
Denis Cappellin
quelle
quelle
fields['ECStruct1']
mitfields.ECStruct1
. Die Verwendung der Punktnotation für den Zugriff auf Objekt-Requisiten wird normalerweise dem Zugriff auf String-Literale vorgezogen.fields.ECStruct1=
ist aber vom TS-Compiler nicht zulässig: Fehler TS2339-Eigenschaft 'ECStruct1' existiert nicht für Typ '{[structName: string]: ECType []; } '.Antworten:
Sie haben hier einige Möglichkeiten:
Deaktivieren Sie einfach die Regel
/* tslint:disable:no-string-literal */ whatever.codeHere() /* tslint:enable:no-string-literal */
Verwenden Sie eine Variable anstelle eines Zeichenfolgenliteral
// instead of fields['ECStruct1'] = ... // do something like let key = 'ECStruct1'; fields[key] = ...
Schreiben / Generieren einer expliziten Schnittstelle
Siehe MartylXs Antwort oben . Im Wesentlichen:
interface ECFieldList { ECStruct1: ECType[]; } export var fields:ECFieldList = { ECStruct1: [ ...
All dies sind vernünftige Lösungen, obwohl ich nicht so ein Fan von # 2 bin, weil es Ihren Code ohne guten Grund durcheinander bringt. Wenn Sie sowieso Code generieren, ist es möglicherweise
fields
eine gute Lösung, einen Typ für wie in # 3 zu generieren .quelle
Sie können die Regel loswerden. Suchen Sie nach
tslint.json
dem Hinzufügen einer Eigenschaft"no-string-literal"
mitfalse
, inrules
::{ "rules": { "no-string-literal": false, ... other rules ...
quelle
Verwenden Sie einfach die wörtliche Annotation der Vorlage.
fields[`ECStruct1`]
quelle
Was ist mit diesem Weg? Ich weiß nicht, ob Sie den Indexer (
[structName: string]: Array<ECType>;
) benötigen oder nicht.interface ECType { name: string; type: string; elementType?: string; } interface ECFieldList { ECStruct1: ECType[]; } export var fields:ECFieldList = { ECStruct1: [ {name: 'foo', type: 'string'}, {name: 'bar', type: 'int'}, {name: 'baz', type: 'bool'}, {name: 'qux', type: 'long'}, {name: 'quux', type: 'ulong'}, {name: 'corge', type: 'array', elementType: 'ECStruct2'}, {name: 'grault', type: 'ECStruct2'} ] };
quelle
interface
mit N Definitionen vonECStruct
und dann die,export var fields...
wo ich die tatsächliche Definition von jedem schreibeECStruct
.no-string-literal
(verhindert den Objektzugriff über String-Literale. - npmjs.com/package/tslint )no-string-literal
global aktiviert und nur in der Datei mit dem obigen Code habe ich sie mit Kommentar deaktiviert/* tslint:disable: no-string-literal */
.fields[variable]
) und die Punktsyntax mit Zeichenfolgen (dhfields.ECStruct1
), und Sie sollten in Ordnung sein.Wahrscheinlich nicht die beste Option, aber mit
fields['ECStruct1'.toString()]
funktioniert auch
quelle
Eine einfache Möglichkeit besteht darin, eine Variable zu definieren, die den Wert von ECStruct1 enthält:
const sampleName = 'ECStruct1';
und erhalten Sie dann Zugriff auf das Objekt, indem Sie die Variable als Index verwenden:
quelle