如何重写代码以避免 TSLint“通过字符串访问对象”

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

更新 : 最后,上面的内容将是一个自生成的文件的一部分,超过300个 ECStruct,所以我希望有类定义(如 ECStruct1)后面跟着它的元描述(如 fields['ECStruct1'])。

89075 次浏览

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

You have a couple options here:

1) Just disable the rule

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

2) Use a variable instead of a string literal

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

3) 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.

Probably not the best option, but using

fields['ECStruct1'.toString()]

works too

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 ...

Just use template literal annotation.

fields[`ECStruct1`]

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] ...

I have faced the same error. but i tried to make use of the type of Headers of Request object and it worked for me. Below is how I managed to resolve the issue.

const objToAdd: { [key: string]: string } = {};
objToAdd.type = 'typeToAdd';
objToAdd.key = 'keyToAdd';
objToAdd.value = 'valueToAdd';

if you see the type { [key: string]: string } tells the TSLint that this object takes keys and values of type string. Similarly, { [key: string]: any } types specifies that the keys are of string type and values of are of any type