TSLint "문자열 리터럴을 통한 개체 액세스"를 방지하기 위해 코드를 다시 작성하는 방법


85

저는 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'].


4
나는 TS를 사용한 적이 있지만 오류보고 코드를보고, 나는 당신이 교체해야 말하고 싶지만 fields['ECStruct1']와 함께 fields.ECStruct1. 점 표기법을 사용하여 객체 소품에 액세스하는 것이 일반적으로 문자열 리터럴 액세스보다 선호됩니다.
Jamie Dixon

1
감사. 이미 시도했지만 fields.ECStruct1=TS 컴파일러에서 허용하지 않습니다. 오류 TS2339 속성 'ECStruct1'이 유형 '{[structName : string] : ECType []에 존재하지 않습니다. } '.
Denis Cappellin 2015 년

답변:


152

여기에 몇 가지 옵션이 있습니다.

규칙을 비활성화하십시오.

/* 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"false에, rules::

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

41

템플릿 리터럴 주석을 사용하십시오.

fields[`ECStruct1`]

4
그것은 바로 경고의 목적을 무너 뜨리는 추악한 속임수입니다. 그러나 그것은 문제를 간단한 방법으로 해결 합니다.
LosManos

구성에 따라 다음과 같은 새로운 경고가 생성 될 수 있습니다.`should be '(인용 부호) tslint (1)
ruble

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

나는 내 질문을 편집하고 더 많은 세부 사항을 추가 했으므로이 의견은 명확해야합니다. 난을 피하기 위해 싶습니다 interfaceN의 정의는 ECStruct다음과 export var fields...나는 모든의 실제 정의를 쓸 경우 ECStruct.
Denis Cappellin 2015 년

tslint에 대한 설정은 무엇입니까? 난 당신이 활성화 추측 no-string-literal(것을 허용하지 문자열 리터럴을 통해 액세스 객체. - npmjs.com/package/tslint을 )
마틴 Vseticka

1
예, 이제 옵션이 no-string-literal전역 적으로 활성화되었으며 위의 코드가있는 파일에서만 주석으로 비활성화했습니다 /* tslint:disable: no-string-literal */.
Denis Cappellin 2015 년

글쎄, 변수 (예 fields[variable])와 함께 대괄호 구문을 사용하고 문자열 (예 fields.ECStruct1)과 함께 점 구문을 사용 하면 괜찮을 것입니다.
Martin Vseticka 2015 년

5

아마도 최선의 선택은 아니지만

fields['ECStruct1'.toString()]

너무 작동합니다


2
이러지 마세요. 린 터는 프로젝트를 설정 한 사람이 린터 규칙을 해킹하지 않고 모범 코드 관행을 따르기를 원하기 때문입니다.
Andy

0

간단한 방법은 ECStruct1의 값을 보유 할 변수를 정의하는 것입니다.

const sampleName = 'ECStruct1';

그런 다음 변수를 인덱스로 사용하여 개체에 액세스합니다.

fields[sampleName] ...
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.