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


81

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

更新:最后,以上内容将是一个超过300ECStruct秒的自生成文件的一部分,因此,我想在类定义(例如ECStruct1)后加上元描述(例如fields['ECStruct1'])。


4
我从来没有使用过TS,但是查看错误并查看代码,我想您需要替换fields['ECStruct1']fields.ECStruct1。与字符串文字访问相比,通常首选使用点表示法访问对象道具。
杰米·迪克森

1
谢谢。我已经尝试过,但是fields.ECStruct1=TS编译器不允许:错误TS2339类型'{[structName:string]:ECType [];中的属性'ECStruct1'不存在。}'。
Denis Cappellin

Answers:


147

您在这里有几个选择:

只是禁用规则

/* 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"falserules

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

39

只需使用模板文字注释即可。

fields[`ECStruct1`]

2
很好很简单。感谢你!
白兰度

4
丑陋的招数使它无法达到警告的目的。但这很简单地解决了我的问题。
LosManos

1
一年骇客!
Kacpers

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ñ的定义ECStruct,然后export var fields...在那里我写的每一个实际的定义ECStruct
Denis Cappellin

您对tslint的设置是什么?我猜您已启用no-string-literal(不允许通过字符串文字访问对象。- npmjs.com/package/tslint
Martin Vseticka 2015年

1
是的,现在我已no-string-literal全局启用该选项,并且仅在具有以上代码的文件中,我已使用comment禁用了该选项/* tslint:disable: no-string-literal */
Denis Cappellin 2015年

好吧,将方括号语法与变量(即 fields[variable])和点语法与字符串(即fields.ECStruct1)一起使用,就可以了。
Martin Vseticka

5

可能不是最好的选择,但是使用

fields['ECStruct1'.toString()]

也可以


快捷方便。
Dani

1
请不要这样做。之所以选择Linter,是因为设置项目的人希望您遵循最佳代码实践,而不是随意修改Linter规则。
安迪

0

一种简单的方法是定义一个变量以保存ECStruct1的值:

const sampleName = 'ECStruct1';

然后,通过使用变量作为索引来访问对象:

fields[sampleName] ...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.