Як переписати код, щоб уникнути TSLint “доступ до об’єкта через рядкові літерали”


85

Я досить новачок у TypeScript, і я хотів би знати, чи існує хороший спосіб переписати код, щоб уникнути помилки TSLint "доступ до об'єкта через рядкові літерали заборонено" в наступному коді

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

Оновлення : наприкінці вміст, наведений вище, буде частиною самогенерованого файлу ECStruct, який триває більше 300 с, тому я хотів би мати визначення класу (наприклад ECStruct1) з подальшим його мета-описом (наприклад fields['ECStruct1']).


4
Я ніколи не використовував TS, але, дивлячись на помилку і дивлячись на код, я б сказав, що вам потрібно замінити fields['ECStruct1']на fields.ECStruct1. Використання точкових позначень для доступу до реквізитів об’єктів, як правило, переважніше, ніж доступ до літерального рядка.
Джеймі Діксон,

1
Дякую. Я вже спробував, але fields.ECStruct1=компілятор TS не дозволяє: Помилка TS2339 Властивість 'ECStruct1' не існує для типу '{[structName: string]: ECType []; } '.
Денис Каппелін

Відповіді:


152

У вас є кілька варіантів тут:

Просто вимкніть правило

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

Використовуйте змінну замість рядкового літералу

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

Написати / створити явний інтерфейс

Дивіться відповідь MartylX вище . По суті:

interface ECFieldList {
    ECStruct1: ECType[];
}

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

Будь-яке з них є розумним рішенням, хоча я не настільки шанувальник №2, тому що він перекручує ваш код без поважних причин. Якщо ви все одно генеруєте код, можливо, генерування типу, fieldsяк у # 3, є гарним рішенням.


48

Ви можете позбутися правила. Шукайте tslint.json, то додати властивість "no-string-literal"з false, в rules::

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

41

Просто використовуйте літеральну анотацію шаблону.

fields[`ECStruct1`]

4
Некрасива хитрість, оскільки вона перемагає мету самого попередження. але це вирішує мою проблему простим способом.
LosManos,

залежно від вашої конфігурації, це може створити нове попередження: `повинно бути '(quotemark) tslint (1)
рубль

6

А як щодо цього шляху? Не знаю, потрібен вам індексатор ( [structName: string]: Array<ECType>;) чи ні.

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

Я відредагував свої запитання та додав більше деталей, тому цей коментар повинен бути зрозумілим. Я хотів би уникнути маючи interfaceз N визначеннями , ECStructа потім , export var fields...коли я пишу фактичне визначення кожного ECStruct.
Денис Каппелін

Які ваші налаштування для tslint? Думаю, ви ввімкнули no-string-literal(забороняє доступ до об’єкта за допомогою рядкових літералів. - npmjs.com/package/tslint )
Мартін Всетіка

1
Так, зараз у мене є опція no-string-literalглобально увімкнена, і лише у файлі з наведеним вище кодом я вимкнув її з коментарем /* tslint:disable: no-string-literal */.
Денис Каппелін

Ну, використовуйте синтаксис дужок зі змінними (тобто fields[variable]) та крапковий синтаксис із рядками (тобто fields.ECStruct1), і ви повинні бути в порядку.
Martin Vseticka,

5

Можливо, не найкращий варіант, але використання

fields['ECStruct1'.toString()]

працює теж


2
Будь ласка, не роби цього. Лінтер існує, тому що особа, яка створила проект, хоче, щоб ви дотримувались найкращих практик коду, а не хаквали правила лінтера.
Енді

0

Простий спосіб полягає у визначенні змінної для зберігання значення ECStruct1:

const sampleName = 'ECStruct1';

а потім отримати доступ до об’єкта, використовуючи змінну як індекс:

fields[sampleName] ...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.