web-dev-qa-db-fra.com

Comment réécrire du code pour éviter TSLint "l'accès aux objets via des littéraux de chaîne"

Je suis assez nouveau dans TypeScript et j'aimerais savoir s'il existe un bon moyen de réécrire le code pour éviter l'erreur TSLint "l'accès aux objets via les littéraux de chaîne n'est pas autorisé" dans le code suivant

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

Mise à jour : À la fin, le contenu ci-dessus fera partie d'un fichier auto-généré avec plus de 300 ECStructs. Je souhaiterais donc que la définition de la classe (par exemple ECStruct1) soit suivie de sa méta-description (par exemple fields['ECStruct1']) .

28
Denis Cappellin

Vous avez deux options ici:

Désactive simplement la règle

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

Utiliser une variable au lieu d'un littéral de chaîne

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

Write/Generate une interface explicite

Voir réponse de MartylX ci-dessus }. Essentiellement:

interface ECFieldList {
    ECStruct1: ECType[];
}

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

Chacune de ces solutions est raisonnable, bien que je ne sois pas aussi fan de la deuxième version, car elle altère votre code sans raison valable. Si vous générez quand même du code, générer un type pour fields comme dans # 3 est une bonne solution.

54
JKillian

Qu'en est-il de cette façon? Je ne sais pas si vous avez besoin de l'indexeur ([structName: string]: Array<ECType>;) ou non.

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

Probablement pas la meilleure option, mais en utilisant 

fields['ECStruct1'.toString()]

fonctionne aussi

1
Vipkry

Vous pouvez vous débarrasser de la règle. Recherchez tslint.json, ajoutez la propriété "no-string-literal" avec false, dans rules ::

{
"rules": {
    "no-string-literal": false,
    ... other rules ...
0
simple_human