2015-10-28 1 views
19

Я довольно новичок в TypeScript, и мне хотелось бы знать, существует ли хороший способ переписать код, чтобы избежать ошибки TSLint. «Доступ к объекту через строковые литералы запрещен»в следующем кодеКак переписать код, чтобы избежать доступа к объекту 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' } 
]; 

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

+0

Я никогда не использовал TS, но, глядя на ошибку и глядя на код, я бы сказал, что вам нужно заменить 'fields ['ECStruct1']' на 'fields.ECStruct1'. Использование точечной нотации для доступа к реквизитам объектов обычно предпочтительнее доступа к строковым литералам. –

+0

Спасибо. Я уже пробовал, но 'fields.ECStruct1 =' не разрешен компилятором TS: Ошибка \t TS2339 Свойство «ECStruct1» не существует в типе «{[structName: string]: ECType []; }». –

ответ

33

У вас есть несколько вариантов здесь:

Просто отключить правило

/* 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's answer above. По существу:

interface ECFieldList { 
    ECStruct1: ECType[]; 
} 

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

Любой из них разумные решения, хотя я не так много поклонника # 2, потому что это коверкая свой код без причины. Если вы все равно генерируете код, возможно, создание типа для fields, как в № 3, является хорошим решением.

2

Как насчет этого пути? Я не знаю, нужен ли вам индекс ([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'} 
    ] 
}; 
+0

Я отредактировал мои вопросы и добавил более подробную информацию, поэтому этот комментарий должен быть ясным. Я хотел бы избежать использования 'interface' с _N_ определениями' ECStruct', а затем 'export var fields ...', где я пишу фактическое определение каждого 'ECStruct'. –

+0

Каковы ваши настройки для tslint? Я думаю, вы включили 'no-string-literal' (запрещает доступ к объектам через строковые литералы. - https://www.npmjs.com/package/tslint) –

+0

Да, теперь у меня есть опция' no-string-literal' глобально включен и только в файле с указанным выше кодом я отключил его с помощью комментария '/ * tslint: disable: no-string-literal * /'. –

Смежные вопросы