Soy bastante nuevo en TypeScript y me gustaría saber si existe una buena manera de reescribir el código para evitar el error TSLint "el acceso al objeto a través de cadenas literales no está permitido" en el siguiente código
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' }
];
Actualización : Al final, el contenido anterior será parte de un archivo autogenerado con más de 300 ECStructs, por lo que me gustaría tener la definición de la clase (por ejemplo ECStruct1) seguida de su metadescripción (por ejemplo fields['ECStruct1']).
                    
                        typescript
                                tslint
                                
                    
                    
                        Denis Cappellin
fuente
                
                fuente

fields['ECStruct1']porfields.ECStruct1. Por lo general, se prefiere el uso de la notación de puntos para acceder a los accesorios de los objetos al acceso literal de cadena.fields.ECStruct1=el compilador TS no lo permite: Error TS2339 La propiedad 'ECStruct1' no existe en el tipo '{[structName: string]: ECType []; } '.Respuestas:
Tienes un par de opciones aquí:
Solo deshabilita la regla
/* tslint:disable:no-string-literal */ whatever.codeHere() /* tslint:enable:no-string-literal */Usa una variable en lugar de una cadena literal
// instead of fields['ECStruct1'] = ... // do something like let key = 'ECStruct1'; fields[key] = ...Escribir / generar una interfaz explícita
Vea la respuesta de MartylX arriba . Esencialmente:
interface ECFieldList { ECStruct1: ECType[]; } export var fields:ECFieldList = { ECStruct1: [ ...Cualquiera de estas son soluciones razonables, aunque no soy tan fan del # 2 porque está alterando tu código sin una buena razón. Si está generando código de todos modos, quizás generar un tipo
fieldscomo en el n. ° 3 sea una buena solución.fuente
Puedes deshacerte de la regla. Busque
tslint.json, el agregar una propiedad"no-string-literal"confalse, enrules:{ "rules": { "no-string-literal": false, ... other rules ...fuente
Simplemente use la anotación literal de plantilla.
fields[`ECStruct1`]fuente
¿Y de esta manera? No sé si necesita el indexador (
[structName: string]: Array<ECType>;) o no.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'} ] };fuente
interfacecon N deECStructy luegoexport var fields...dónde escribo la definición real de cadaECStruct.no-string-literal(no permite el acceso a objetos a través de literales de cadena. - npmjs.com/package/tslint )no-string-literalhabilitada globalmente y solo en el archivo con el código anterior la deshabilité con comentario/* tslint:disable: no-string-literal */.fields[variable]) y la sintaxis de puntos con cadenas (es decirfields.ECStruct1) y debería estar bien.Probablemente no sea la mejor opción, pero usar
fields['ECStruct1'.toString()]funciona tambien
fuente
Una forma sencilla es definir una variable para contener el valor de ECStruct1:
const sampleName = 'ECStruct1';y luego, obtenga acceso al objeto usando la variable como índice:
fuente