问题
I'm pretty new to TypeScript and I would like to know if there exists a good way to rewrite code to avoid TSLint error "object access via string literals is disallowed" in the following code
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: At the end the content above will be part of a self-generated file with more than 300 ECStructs, so I would like to have the class definition (e.g. ECStruct1) followed by its meta-description (e.g. fields['ECStruct1']).
回答1:
You have a couple options here:
Just disable the rule
/* tslint:disable:no-string-literal */
whatever.codeHere()
/* tslint:enable:no-string-literal */
Use a variable instead of a string literal
// instead of 
fields['ECStruct1'] = ...
// do something like
let key = 'ECStruct1';
fields[key] = ...
Write/Generate an explicit interface
See MartylX's answer above. Essentially:
interface ECFieldList {
    ECStruct1: ECType[];
}
export var fields:ECFieldList = {
    ECStruct1: [
        ...
Any of these are reasonable solutions, although I'm not as much of a fan of #2 because it's mangling up your code for no good reason. If you're generating code anyways, perhaps generating a type for fields as in #3 is a good solution.
回答2:
You can get rid of the rule. Look for tslint.json, the add a property "no-string-literal" with false, in rules::
{
"rules": {
    "no-string-literal": false,
    ... other rules ...
    回答3:
Just use template literal annotation.
fields[`ECStruct1`]
    回答4:
Probably not the best option, but using
fields['ECStruct1'.toString()]
works too
回答5:
What about this way? I don't know if you need the indexer ([structName: string]: Array<ECType>;) or not.
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'}
    ]
};
    回答6:
A simple way is to define a variable to hold the value of ECStruct1:
const sampleName = 'ECStruct1';
and then, get access to the object by using the variable as index:
fields[sampleName] ...
    来源:https://stackoverflow.com/questions/33387090/how-to-rewrite-code-to-avoid-tslint-object-access-via-string-literals