Denis Cappellin Denis Cappellin -4 years ago 438
TypeScript Question

How to rewrite code to avoid TSLint "object access via string literals"

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
ECStruct
s, so I would like to have the class definition (e.g.
ECStruct1
) followed by its meta-description (e.g.
fields['ECStruct1']
).

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download