2015-10-28 8 views
19

Ich bin ziemlich neu in TypeScript und ich würde gerne wissen, ob es eine gute Möglichkeit gibt, Code zu schreiben, um TSLint Fehler zu vermeiden "Objektzugriff über Stringliterale ist im folgenden Code nicht zulässig“Wie schreibe ich Code um TSLint zu vermeiden "Objektzugriff über Stringliterale"

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' } 
]; 

aktualisieren: Am Ende wird der Inhalt oben mit mehr als 300 ECStruct s Teil einer selbst erzeugten Datei sein, so würde Ich mag die Klassendefinition (zB ECStruct1) gefolgt von seiner Meta-Beschreibung (zB fields['ECStruct1']).

+0

Ich habe nie TS verwendet, aber mit Blick auf den Fehler und Blick auf den Code, würde ich sagen, Sie müssen ersetzen 'Felder ['ECStruct1']' mit 'fields.ECStruct1'. Die Verwendung der Punktnotation für den Zugriff auf Objektrequisiten wird normalerweise gegenüber dem Zeichenfolgenliteralzugriff bevorzugt. –

+0

Danke. Ich habe es schon ausprobiert, aber 'fields.ECStruct1 =' ist vom TS-Compiler nicht erlaubt: Fehler \t TS2339 Eigenschaft 'ECStruct1' existiert nicht beim Typ '{[structName: string]: ECType []; } '. –

Antwort

33

Sie haben ein paar Optionen hier:

Nur die Regel deaktivieren

/* tslint:disable:no-string-literal */ 
whatever.codeHere() 
/* tslint:enable:no-string-literal */ 

Verwenden Sie eine Variable anstelle eines Zeichenfolgenliterals

// instead of 
fields['ECStruct1'] = ... 
// do something like 
let key = 'ECStruct1'; 
fields[key] = ... 

Schreiben/Generieren einer expliziten Schnittstelle

Siehe MartylX's answer above. Im Wesentlichen:

interface ECFieldList { 
    ECStruct1: ECType[]; 
} 

export var fields:ECFieldList = { 
    ECStruct1: [ 
     ... 

davon Alle sind vernünftige Lösungen, obwohl ich nicht so viel von einem Fan von bin # 2, weil es Ihren Code für keinen guten Grund hat Mangeln auf. Wenn Sie sowieso Code generieren, ist es vielleicht eine gute Lösung, einen Typ für fields wie in # 3 zu generieren.

2

Was ist mit diesem Weg? Ich weiß nicht, ob Sie den Indexer ([structName: string]: Array<ECType>;) brauchen 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'} 
    ] 
}; 
+0

Ich habe meine Fragen bearbeitet und weitere Details hinzugefügt, daher sollte dieser Kommentar klar sein. Ich möchte vermeiden, die 'Schnittstelle' mit _N_ Definitionen von' ECStruct' und dann die 'export var Felder ...' zu haben, wo ich die tatsächliche Definition von jedem 'ECStruct' schreibe. –

+0

Was sind deine Einstellungen für tslint? Ich glaube, Sie haben 'no-string-literal' aktiviert (Objektzugriff über Stringliterale nicht erlaubt. - https://www.npmjs.com/package/tslint) –

+0

Ja, jetzt habe ich die Option' no-string-literal' global aktiviert und nur in der Datei mit dem obigen Code habe ich es mit dem Kommentar '/ * tslint: disable: no-string-literal * /' deaktiviert. –